nhb-toolbox 4.0.36 → 4.0.44

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,7 +8,7 @@ const hsl = (0, random_1.generateRandomHSLColor)();
8
8
  const { hex, rgb } = (0, convert_1.convertColorCode)(hsl);
9
9
  /**
10
10
  * * Class representing a color and its conversions among `Hex`, `Hex8` `RGB`, `RGBA`, `HSL` and `HSLA` formats.
11
- * * It has 1 instance method `applyOpacity()` to apply opacity to `Hex`, `Hex8` `RGB`, `RGBA`, `HSL` or `HSLA` color.
11
+ * * It has 13 instance methods to manipulate and play with the color values.
12
12
  * * It has 6 static methods that can be used to check if a color is in `Hex`, `Hex8` `RGB`, `RGBA`, `HSL` or `HSLA` format.
13
13
  *
14
14
  * @property hex - The color in `Hex` format.
@@ -41,7 +41,7 @@ class Color {
41
41
  * If no color is passed, a random color will be generated.
42
42
  *
43
43
  * Additionally:
44
- * - Use `.applyOpacity(opacity)` to modify or add opacity to the color.
44
+ * - It has 13 instance methods to manipulate and play with the color values.
45
45
  * - Use static methods like `Color.isHex6(color)` to validate color strings.
46
46
  *
47
47
  * @param toConvert - An optional input color string in any supported format (`Hex`, `Hex8`, `RGB`, `RGBA`, `HSL`, or `HSLA`) to convert in all other (includes the current format) formats.
@@ -118,12 +118,12 @@ class Color {
118
118
  yield this.hsla;
119
119
  }
120
120
  /**
121
- * * Applies or modifies the opacity of a color.
122
- * - For solid colors (Hex6/RGB/HSL): Adds an alpha channel with the specified opacity
123
- * - For alpha colors (Hex8/RGBA/HSLA): Updates the existing alpha channel
121
+ * @instance Applies or modifies the opacity of a color. Mutate the original instance.
122
+ * - For solid colors (Hex6/RGB/HSL): Adds an alpha channel with the specified opacity.
123
+ * - For alpha colors (Hex8/RGBA/HSLA): Updates the existing alpha channel.
124
124
  *
125
- * @param opacity - A number between 0-100 representing the opacity percentage
126
- * @returns An object containing all color formats with the applied opacity
125
+ * @param opacity - A number between 0-100 representing the opacity percentage.
126
+ * @returns A new instance of `Color` containing all color formats with the applied opacity.
127
127
  *
128
128
  * @example
129
129
  * const color = new Color("#ff0000");
@@ -141,14 +141,168 @@ class Color {
141
141
  const alphaDecimal = validOpacity / 100;
142
142
  const rgbValues = (0, helpers_1._extractSolidColorValues)(this.rgb);
143
143
  const hslValues = (0, helpers_1._extractSolidColorValues)(this.hsl);
144
- return {
144
+ return Color.#fromParts({
145
145
  hex: this.hex.slice(0, 7).toUpperCase(),
146
146
  hex8: `${this.hex.slice(0, 7)}${alphaHex}`.toUpperCase(),
147
147
  rgb: `rgb(${rgbValues[0]}, ${rgbValues[1]}, ${rgbValues[2]})`,
148
148
  rgba: `rgba(${rgbValues[0]}, ${rgbValues[1]}, ${rgbValues[2]}, ${alphaDecimal})`,
149
149
  hsl: `hsl(${hslValues[0]}, ${hslValues[1]}%, ${hslValues[2]}%)`,
150
150
  hsla: `hsla(${hslValues[0]}, ${hslValues[1]}%, ${hslValues[2]}%, ${alphaDecimal})`,
151
+ });
152
+ }
153
+ /**
154
+ * @instance Darkens the color by reducing the lightness by the given percentage.
155
+ * @param percent - The percentage to darken (0–100).
156
+ * @returns A new `Color` instance with the modified darkness.
157
+ */
158
+ applyDarkness(percent) {
159
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
160
+ const newL = Math.max(0, l - percent);
161
+ const newHSL = `hsl(${h}, ${s}%, ${newL}%)`;
162
+ return new Color(newHSL);
163
+ }
164
+ /**
165
+ * @instance Lightens the color by increasing the lightness by the given percentage.
166
+ * @param percent - The percentage to brighten (0–100).
167
+ * @returns A new `Color` instance with the modified lightness.
168
+ */
169
+ applyBrightness(percent) {
170
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
171
+ const newL = Math.min(100, l + percent);
172
+ const newHSL = `hsl(${h}, ${s}%, ${newL}%)`;
173
+ return new Color(newHSL);
174
+ }
175
+ /**
176
+ * @instance Reduces the saturation of the color to make it appear duller.
177
+ * @param percent - The percentage to reduce saturation (0–100).
178
+ * @returns A new `Color` instance with the modified saturation.
179
+ */
180
+ applyDullness(percent) {
181
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
182
+ const newS = Math.max(0, s - percent);
183
+ const newHSL = `hsl(${h}, ${newS}%, ${l}%)`;
184
+ return new Color(newHSL);
185
+ }
186
+ /**
187
+ * @instance Softens the color toward white by reducing saturation and increasing lightness based on a percentage.
188
+ * - *This creates a soft UI-like white shade effect (similar to some UI libraries' light color scale).*
189
+ * @param percent - Value from 0 to 100 representing how far to push the color toward white.
190
+ * @returns A new `Color` instance shifted toward white.
191
+ */
192
+ applyWhiteShade(percent) {
193
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
194
+ // Cap values to avoid overshooting
195
+ const newS = Math.max(0, s - (s * percent) / 100);
196
+ const newL = Math.min(100, l + ((100 - l) * percent) / 100);
197
+ const newHSL = `hsl(${h}, ${newS}%, ${newL}%)`;
198
+ return new Color(newHSL);
199
+ }
200
+ /**
201
+ * @instance Blends the current color with another color based on the given weight.
202
+ * @param other - The color in any 6 `(Hex, Hex8 RGB, RGBA, HSL or HSLA)` to blend with.
203
+ * @param weight - A number from 0 to 1 indicating the weight of the other color. Defaults to `0.5`.
204
+ * - `weight = 0` → only the original color (this)
205
+ * - `weight = 1` → only the other color
206
+ * - `weight = 0.5` → equal blend between the two
207
+ * @returns A new `Color` instance representing the blended result.
208
+ */
209
+ blendWith(other, weight = 0.5) {
210
+ const w = Math.max(0, Math.min(1, weight));
211
+ const converted = new Color(other);
212
+ const rgb1 = (0, helpers_1._extractSolidColorValues)(this.rgb);
213
+ const rgb2 = (0, helpers_1._extractSolidColorValues)(converted.rgb);
214
+ const blended = rgb1.map((c, i) => Math.round(c * (1 - w) + rgb2[i] * w));
215
+ const blendedRGB = `rgb(${blended[0]}, ${blended[1]}, ${blended[2]})`;
216
+ return new Color(blendedRGB);
217
+ }
218
+ /**
219
+ * @instance Calculates the contrast ratio between this color and another color (WCAG).
220
+ * @param other - The other color to compare against.
221
+ * @returns A number representing the contrast ratio (rounded to 2 decimal places).
222
+ */
223
+ contrastRatio(other) {
224
+ const newColor = new Color(other);
225
+ const luminance = (rgb) => {
226
+ const [r, g, b] = (0, helpers_1._extractSolidColorValues)(rgb).map((v) => {
227
+ const c = v / 255;
228
+ return c <= 0.03928 ?
229
+ c / 12.92
230
+ : Math.pow((c + 0.055) / 1.055, 2.4);
231
+ });
232
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
151
233
  };
234
+ const lum1 = luminance(this.rgb);
235
+ const lum2 = luminance(newColor.rgb);
236
+ const brighter = Math.max(lum1, lum2);
237
+ const darker = Math.min(lum1, lum2);
238
+ const ratio = (brighter + 0.05) / (darker + 0.05);
239
+ return Math.round(ratio * 100) / 100;
240
+ }
241
+ /**
242
+ * @instance Returns the complementary color by rotating the hue 180 degrees.
243
+ * @returns A new Color that is the complement of the current color.
244
+ */
245
+ getComplementaryColor() {
246
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
247
+ const newHue = (h + 180) % 360;
248
+ const newHSL = `hsl(${newHue}, ${s}%, ${l}%)`;
249
+ return new Color(newHSL);
250
+ }
251
+ /**
252
+ * @instance Generates a color scheme of analogous colors, including the base color.
253
+ * Analogous colors are next to each other on the color wheel (±30°).
254
+ * @returns An array of three Color instances: [base, left, right].
255
+ */
256
+ getAnalogousColors() {
257
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
258
+ const left = `hsl(${(h + 330) % 360}, ${s}%, ${l}%)`;
259
+ const right = `hsl(${(h + 30) % 360}, ${s}%, ${l}%)`;
260
+ return [this, new Color(left), new Color(right)];
261
+ }
262
+ /**
263
+ * @instance Generates a color triad scheme including the base color.
264
+ * Triadic colors are evenly spaced (120° apart) on the color wheel.
265
+ * @returns An array of three Color instances: [base, triad1, triad2].
266
+ */
267
+ getTriadColors() {
268
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
269
+ const c1 = `hsl(${(h + 120) % 360}, ${s}%, ${l}%)`;
270
+ const c2 = `hsl(${(h + 240) % 360}, ${s}%, ${l}%)`;
271
+ return [this, new Color(c1), new Color(c2)];
272
+ }
273
+ /**
274
+ * @instance Generates a tetradic color scheme including the base color.
275
+ * Tetradic colors form a rectangle on the color wheel (90° apart).
276
+ * @returns An array of four Color instances: [base, tetrad1, tetrad2, tetrad3].
277
+ */
278
+ getTetradColors() {
279
+ const [h, s, l] = (0, helpers_1._extractSolidColorValues)(this.hsl);
280
+ const c1 = `hsl(${(h + 90) % 360}, ${s}%, ${l}%)`;
281
+ const c2 = `hsl(${(h + 180) % 360}, ${s}%, ${l}%)`;
282
+ const c3 = `hsl(${(h + 270) % 360}, ${s}%, ${l}%)`;
283
+ return [this, new Color(c1), new Color(c2), new Color(c3)];
284
+ }
285
+ /**
286
+ * @instance Gets the `WCAG` accessibility rating between this and another color.
287
+ * @param other - The other color to test contrast against.
288
+ * @returns 'Fail', 'AA', or 'AAA' based on `WCAG 2.1` contrast standards.
289
+ */
290
+ getWCAGRating(other) {
291
+ const ratio = this.contrastRatio(other);
292
+ if (ratio >= 7)
293
+ return 'AAA';
294
+ if (ratio >= 4.5)
295
+ return 'AA';
296
+ return 'Fail';
297
+ }
298
+ /**
299
+ * @instance Determines if the color is light based on its perceived brightness.
300
+ * @returns `true` if light, `false` if dark.
301
+ */
302
+ isLightColor() {
303
+ const [r, g, b] = (0, helpers_1._extractSolidColorValues)(this.rgb);
304
+ const brightness = (r * 299 + g * 587 + b * 114) / 1000;
305
+ return brightness > 127.5;
152
306
  }
153
307
  /**
154
308
  * @static Checks if a color is in `Hex6` format.
@@ -169,40 +323,40 @@ class Color {
169
323
  return /^#[0-9A-Fa-f]{8}$/.test(color);
170
324
  }
171
325
  /**
172
- * @static Checks if a color is in `RGB` format.
326
+ * @static Checks if a color is in `RGB` format and within valid ranges.
173
327
  *
174
328
  * @param color Color to check.
175
- * @returns Boolean: `true` if it's an `RGB` color, `false` if not.
329
+ * @returns `true` if it's a `RGB` color, `false` if not.
176
330
  */
177
331
  static isRGB(color) {
178
- return /^rgb\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\)$/.test(color);
332
+ return (0, helpers_1._isRGB)(color);
179
333
  }
180
334
  /**
181
- * @static Checks if a color is in `RGBA` format.
335
+ * @static Checks if a color is in `RGBA` format and within valid ranges.
182
336
  *
183
337
  * @param color Color to check.
184
- * @returns Boolean: `true` if it's an `RGBA` color, `false` if not.
338
+ * @returns `true` if it's a `RGBA` color, `false` if not.
185
339
  */
186
340
  static isRGBA(color) {
187
- return /^rgba\(\d{1,3},\s*\d{1,3},\s*\d{1,3},\s*(0|1|0?\.\d+)\)$/.test(color);
341
+ return (0, helpers_1._isRGBA)(color);
188
342
  }
189
343
  /**
190
- * @static Checks if a color is in `HSL` format.
344
+ * @static Checks if a color is in `HSL` format and within valid ranges.
191
345
  *
192
346
  * @param color Color to check.
193
- * @returns Boolean: `true` if it's an `HSL` color, `false` if not.
347
+ * @returns `true` if it's a `HSL` color, `false` if not.
194
348
  */
195
349
  static isHSL(color) {
196
- return /^hsl\(\d{1,3},\s*\d{1,3}%,\s*\d{1,3}%\)$/.test(color);
350
+ return (0, helpers_1._isHSL)(color);
197
351
  }
198
352
  /**
199
- * @static Checks if a color is in `HSLA` format.
353
+ * @static Checks if a color is in `HSLA` format and within valid ranges.
200
354
  *
201
355
  * @param color Color to check.
202
- * @returns Boolean: `true` if it's an `HSLA` color, `false` if not.
356
+ * @returns `true` if it's a `HSLA` color, `false` if not.
203
357
  */
204
358
  static isHSLA(color) {
205
- return /^hsla\(\d{1,3},\s*\d{1,3}%,\s*\d{1,3}%,\s*(0|1|0?\.\d+)\)$/.test(color);
359
+ return (0, helpers_1._isHSLA)(color);
206
360
  }
207
361
  /**
208
362
  * @private Converts the given color to all other formats while preserving the original.
@@ -237,5 +391,20 @@ class Color {
237
391
  }
238
392
  throw new Error(`Unrecognized color format: ${color}`);
239
393
  }
394
+ /**
395
+ * @private @static Internal factory to create a Color instance from parsed parts.
396
+ * @param parts All the color parts as object.
397
+ * @returns An instance of `Color`.
398
+ */
399
+ static #fromParts(parts) {
400
+ const color = Object.create(Color.prototype);
401
+ color.hex = parts.hex;
402
+ color.hex8 = parts.hex8;
403
+ color.rgb = parts.rgb;
404
+ color.rgba = parts.rgba;
405
+ color.hsl = parts.hsl;
406
+ color.hsla = parts.hsla;
407
+ return color;
408
+ }
240
409
  }
241
410
  exports.Color = Color;
@@ -2,12 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports._extractAlphaColorValues = exports._extractSolidColorValues = exports._isSimilarToLast = exports._generateRandomHSL = exports._applyOpacity = exports._convertOpacityToHex = void 0;
4
4
  exports._isHex6 = _isHex6;
5
- exports._isRGB = _isRGB;
6
- exports._isHSL = _isHSL;
7
5
  exports._isHex8 = _isHex8;
6
+ exports._isRGB = _isRGB;
8
7
  exports._isRGBA = _isRGBA;
8
+ exports._isHSL = _isHSL;
9
9
  exports._isHSLA = _isHSLA;
10
10
  exports._isValidAlpha = _isValidAlpha;
11
+ exports._isValidRGBComponent = _isValidRGBComponent;
12
+ exports._isValidHue = _isValidHue;
13
+ exports._isValidPercentage = _isValidPercentage;
11
14
  /**
12
15
  * * Converts opacity percentage (0-100) to a 2-digit hex string.
13
16
  *
@@ -97,7 +100,7 @@ const _extractAlphaColorValues = (colorString) => {
97
100
  };
98
101
  exports._extractAlphaColorValues = _extractAlphaColorValues;
99
102
  /**
100
- * * Checks if a color is in `Hex` format.
103
+ * @private Checks if a color is in `Hex` format.
101
104
  *
102
105
  * @param color Color to check.
103
106
  * @returns Boolean: `true` if it's a `Hex` color, `false` if not.
@@ -106,58 +109,92 @@ function _isHex6(color) {
106
109
  return /^#[0-9A-Fa-f]{6}$/.test(color);
107
110
  }
108
111
  /**
109
- * * Checks if a color is in `RGB` format.
112
+ * @private Checks if a color is in `Hex8` format.
110
113
  *
111
114
  * @param color Color to check.
112
- * @returns Boolean: `true` if it's an `RGB` color, `false` if not.
115
+ * @returns Boolean: `true` if it's a `Hex8` color, `false` if not.
113
116
  */
114
- function _isRGB(color) {
115
- return /^rgb\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\)$/.test(color);
117
+ function _isHex8(color) {
118
+ return /^#[0-9A-Fa-f]{8}$/.test(color);
116
119
  }
117
120
  /**
118
- * * Checks if a color is in `HSL` format.
121
+ * @private Checks if a color is in `RGB` format and within valid ranges.
119
122
  *
120
123
  * @param color Color to check.
121
- * @returns Boolean: `true` if it's an `HSL` color, `false` if not.
124
+ * @returns `true` if it's a `RGB` color, `false` if not.
122
125
  */
123
- function _isHSL(color) {
124
- return /^hsl\(\d{1,3},\s*\d{1,3}%,\s*\d{1,3}%\)$/.test(color);
126
+ function _isRGB(color) {
127
+ const match = color.match(/^rgb\(\s*(\d{1,3}(?:\.\d+)?),\s*(\d{1,3}(?:\.\d+)?),\s*(\d{1,3}(?:\.\d+)?)\s*\)$/);
128
+ if (!match)
129
+ return false;
130
+ const [r, g, b] = match.slice(1).map(Number);
131
+ return (_isValidRGBComponent(r) &&
132
+ _isValidRGBComponent(g) &&
133
+ _isValidRGBComponent(b));
125
134
  }
126
135
  /**
127
- * @static
128
- * Checks if a color is in `Hex8` format.
136
+ * @private Checks if a color is in `RGBA` format and within valid ranges.
129
137
  *
130
138
  * @param color Color to check.
131
- * @returns Boolean: `true` if it's a `Hex8` color, `false` if not.
139
+ * @returns `true` if it's a `RGBA` color, `false` if not.
132
140
  */
133
- function _isHex8(color) {
134
- return /^#[0-9A-Fa-f]{8}$/.test(color);
141
+ function _isRGBA(color) {
142
+ const match = color.match(/^rgba\(\s*(\d{1,3}(?:\.\d+)?),\s*(\d{1,3}(?:\.\d+)?),\s*(\d{1,3}(?:\.\d+)?),\s*(0|1|0?\.\d+)\s*\)$/);
143
+ if (!match)
144
+ return false;
145
+ const [r, g, b, a] = match.slice(1).map(Number);
146
+ return (_isValidRGBComponent(r) &&
147
+ _isValidRGBComponent(g) &&
148
+ _isValidRGBComponent(b) &&
149
+ _isValidAlpha(a));
135
150
  }
136
151
  /**
137
- * @static
138
- * Checks if a color is in `RGBA` format.
152
+ * @private Checks if a color is in `HSL` format and within valid ranges.
139
153
  *
140
154
  * @param color Color to check.
141
- * @returns Boolean: `true` if it's an `RGBA` color, `false` if not.
155
+ * @returns `true` if it's a `HSL` color, `false` if not.
142
156
  */
143
- function _isRGBA(color) {
144
- return /^rgba\(\d{1,3},\s*\d{1,3},\s*\d{1,3},\s*(0|1|0?\.\d+)\)$/.test(color);
157
+ function _isHSL(color) {
158
+ const match = color.match(/^hsl\(\s*(\d{1,3}(?:\.\d+)?),\s*(\d{1,3}(?:\.\d+)?)%,\s*(\d{1,3}(?:\.\d+)?)%\s*\)$/);
159
+ if (!match)
160
+ return false;
161
+ const [h, s, l] = match.slice(1).map(Number);
162
+ return _isValidHue(h) && _isValidPercentage(s) && _isValidPercentage(l);
145
163
  }
146
164
  /**
147
- * @static
148
- * Checks if a color is in `HSLA` format.
165
+ * @private Checks if a color is in `HSLA` format and within valid ranges.
149
166
  *
150
167
  * @param color Color to check.
151
- * @returns Boolean: `true` if it's an `HSLA` color, `false` if not.
168
+ * @returns `true` if it's a `HSLA` color, `false` if not.
152
169
  */
153
170
  function _isHSLA(color) {
154
- return /^hsla\(\d{1,3},\s*\d{1,3}%,\s*\d{1,3}%,\s*(0|1|0?\.\d+)\)$/.test(color);
171
+ const match = color.match(/^hsla\(\s*(\d{1,3}(?:\.\d+)?),\s*(\d{1,3}(?:\.\d+)?)%,\s*(\d{1,3}(?:\.\d+)?)%,\s*(0|1|0?\.\d+)\s*\)$/);
172
+ if (!match)
173
+ return false;
174
+ const [h, s, l, a] = match.slice(1).map(Number);
175
+ return (_isValidHue(h) &&
176
+ _isValidPercentage(s) &&
177
+ _isValidPercentage(l) &&
178
+ _isValidAlpha(a));
155
179
  }
156
180
  /**
157
- * * Type guard to validate alpha value.
181
+ * @private Checks if a number is valid alpha value.
182
+ *
158
183
  * @param value Alpha value to check.
159
- * @returns Boolean: `true` if it's a valid alpha value, `false` if not.
184
+ * @returns `true` if it's a valid alpha value, `false` if not.
160
185
  */
161
186
  function _isValidAlpha(value) {
162
187
  return value >= 0 && value <= 1 && !isNaN(value);
163
188
  }
189
+ /** * @private Validates RGB component (0–255). */
190
+ function _isValidRGBComponent(value) {
191
+ return value >= 0 && value <= 255;
192
+ }
193
+ /** * @private Validates HSL hue (0–360). */
194
+ function _isValidHue(value) {
195
+ return value >= 0 && value <= 360;
196
+ }
197
+ /** * @private Validates HSL percentage components (0–100). */
198
+ function _isValidPercentage(value) {
199
+ return value >= 0 && value <= 100;
200
+ }
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateQueryParams = void 0;
3
+ exports.parseQueryString = exports.generateQueryParams = void 0;
4
4
  exports.getQueryParams = getQueryParams;
5
5
  exports.updateQueryParam = updateQueryParam;
6
6
  const objectify_1 = require("../object/objectify");
7
+ const sanitize_1 = require("../object/sanitize");
8
+ const utils_1 = require("../utils");
7
9
  /**
8
10
  * * Utility to generate query parameters from an object.
9
11
  *
@@ -53,3 +55,28 @@ function updateQueryParam(key, value) {
53
55
  url.searchParams.set(key, value);
54
56
  window.history.replaceState({}, '', url.toString());
55
57
  }
58
+ /**
59
+ * Parses a query string (with optional `?` prefix) into an object.
60
+ * Supports multiple values for the same key by returning arrays.
61
+ * Optionally parses primitive string values into actual types (e.g., "1" → 1, "true" → true).
62
+ *
63
+ * @param query - The query string to parse.
64
+ * @param parsePrimitives - Whether to convert stringified primitives into real values (default: true).
65
+ * @returns An object where keys are strings and values can be string, array, number, boolean, or null.
66
+ */
67
+ const parseQueryString = (query, parsePrimitives = true) => {
68
+ const params = new URLSearchParams(query.startsWith('?') ? query.slice(1) : query);
69
+ const entries = {};
70
+ for (const [key, value] of params.entries()) {
71
+ if (key in entries) {
72
+ const current = entries[key];
73
+ const array = Array.isArray(current) ? [...current, value] : [current, value];
74
+ entries[key] = parsePrimitives ? (0, utils_1.deepParsePrimitives)(array) : array;
75
+ }
76
+ else {
77
+ entries[key] = value;
78
+ }
79
+ }
80
+ return parsePrimitives ? (0, sanitize_1.parseObjectValues)(entries) : entries;
81
+ };
82
+ exports.parseQueryString = parseQueryString;
package/dist/cjs/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMemoizedFibonacci = exports.getFibonacciSeriesMemo = exports.getFibonacciSeries = exports.getFibonacciNumbers = exports.getFibonacci = exports.generateFibonacci = exports.fibonacciGenerator = exports.calculatePercentage = exports.sumOfNumbers = exports.sumNumbers = exports.sumDigits = exports.reverseNumber = exports.getSumOfNumbers = exports.getRandomNumber = exports.getAverageOfNumbers = exports.getAverage = exports.convertToDecimal = exports.calculateLCM = exports.calculateLCD = exports.calculateHCF = exports.calculateGCD = exports.calculateAverage = exports.countWordsInString = exports.wordCount = exports.countWords = exports.levenshteinDistance = exports.getLevenshteinDistance = exports.extractNumbersFromString = exports.slugifyString = exports.reverseString = exports.replaceAllInString = exports.normalizeString = exports.maskString = exports.formatWithPlural = exports.formatUnitWithPlural = exports.formatNumberWithPluralUnit = exports.extractURLs = exports.extractEmails = exports.convertStringCase = exports.isSnakeCase = exports.isPascalCase = exports.isPalindrome = exports.isKebabCase = exports.isEmojiOnly = exports.isCamelCase = exports.generateAnagrams = exports.truncateString = exports.trimString = exports.generateRandomID = exports.capitalizeString = void 0;
3
+ exports.getMemoizedFibonacci = exports.getFibonacciSeriesMemo = exports.getFibonacciSeries = exports.getFibonacciNumbers = exports.getFibonacci = exports.generateFibonacci = exports.fibonacciGenerator = exports.calculatePercentage = exports.sumOfNumbers = exports.sumNumbers = exports.sumDigits = exports.reverseNumber = exports.getSumOfNumbers = exports.getRandomNumber = exports.getAverageOfNumbers = exports.getAverage = exports.convertToDecimal = exports.calculateLCM = exports.calculateLCD = exports.calculateHCF = exports.calculateGCD = exports.calculateAverage = exports.wordCount = exports.levenshteinDistance = exports.getLevenshteinDistance = exports.extractNumbersFromString = exports.countWordsInString = exports.countWords = exports.slugifyString = exports.reverseString = exports.replaceAllInString = exports.normalizeString = exports.maskString = exports.formatWithPlural = exports.formatUnitWithPlural = exports.formatNumberWithPluralUnit = exports.extractURLs = exports.extractEmails = exports.convertStringCase = exports.isSnakeCase = exports.isPascalCase = exports.isPalindrome = exports.isKebabCase = exports.isEmojiOnly = exports.isCamelCase = exports.generateAnagrams = exports.truncateString = exports.trimString = exports.generateRandomID = exports.capitalizeString = void 0;
4
4
  exports.convertRgbaToHsla = exports.convertRgbaToHex8 = exports.convertHslToRgb = exports.convertHslToHex = exports.convertHslaToRgba = exports.convertHslaToHex8 = exports.convertHexToRgb = exports.convertHexToHsl = exports.convertHex8ToRgba = exports.convertHex8ToHsla = exports.convertColorCode = exports.generateRandomHSLColor = exports.generateRandomColorInHexRGB = exports.getColorForInitial = exports.getNumbersInRange = exports.roundToNearestInterval = exports.roundToNearest = exports.roundNumberToNearestInterval = exports.roundNumber = exports.numberToOrdinal = exports.getRandomFloat = exports.getRandomDecimal = exports.getOrdinalNumber = exports.getOrdinal = exports.formatCurrency = exports.convertToOrdinal = exports.convertNumberToOrdinal = exports.convertNumberToCurrency = exports.clampNumber = exports.cardinalToOrdinal = exports.isPrimeNumber = exports.isPrime = exports.getPrimeNumbers = exports.findPrimeNumbers = exports.numberToWords = exports.convertToRomanNumerals = exports.convertNumberToWords = exports.isPerfectSquare = exports.isParOfFibonacciSeries = exports.isParOfFibonacci = exports.isOddNumber = exports.isOdd = exports.isMultiple = exports.isInvalidNumbers = exports.isFibonacci = exports.isEvenNumber = exports.isEven = exports.areInvalidNumbers = exports.getNthFibonacci = exports.getMemoizedFibonacciSeries = void 0;
5
5
  exports.getDuplicatesFromArray = exports.getDuplicates = exports.findMissingElements = exports.extractMissingElements = exports.extractDuplicatesFromArray = exports.extractDuplicates = exports.createOptionsArray = exports.sortAnArray = exports.shuffleArray = exports.isValidEmptyArray = exports.isInvalidOrEmptyArray = exports.getLastArrayElement = exports.flattenArray = exports.filterArrayOfObjects = exports.minutesToUTCOffset = exports.getTotalMinutesFromUTC = exports.getTotalMinutesFromTime = exports.getTotalMinutes = exports.getTimeStringFromUTC = exports.getMinutesFromUTC = exports.getCurrentTime = exports.getCurrentDateTime = exports.formatUTCOffset = exports.extractTotalMinutesFromTime = exports.extractTimeStringFromUTC = exports.extractTimeFromUTC = exports.extractMinutesFromUTC = exports.extractHourMinute = exports.convertMinutesToUTCOffset = exports.chronusts = exports.chronusjs = exports.chronus = exports.chronosts = exports.chronosjs = exports.chronos = exports.Chronus = exports.Chronos = exports.isValidUTCOffSet = exports.isValidUTC = exports.isValidTimeString = exports.isValidTime = exports.isLeapYear = exports.greet = exports.getGreeting = exports.generateGreeting = exports.Colour = exports.Color = exports.convertRgbToRgba = exports.convertRgbToHsl = exports.convertRgbToHex = void 0;
6
- exports.updateQueryParam = exports.getQueryParams = exports.generateQueryParams = exports.formatQueryParams = exports.createQueryParams = exports.remapObjectFields = exports.remapFields = exports.pickObjectFieldsByCondition = exports.pickObjectFields = exports.pickFieldsByCondition = exports.pickFields = exports.convertObjectValues = exports.sanitizeData = exports.parseStringifiedValues = exports.parseStringifiedPrimitives = exports.parseStringifiedObjectValues = exports.parsePrimitives = exports.parsePrimitiveData = exports.parseObjectValues = exports.mergeObjects = exports.mergeAndFlattenObjects = exports.flattenObjectKeyValue = exports.flattenObjectDotNotation = exports.extractUpdatedFields = exports.extractUpdatedAndNewFields = exports.extractNewFields = exports.countObjectFields = exports.cloneObject = exports.isValidFormData = exports.isOriginFileObj = exports.isFileUpload = exports.isFileList = exports.isFileArray = exports.isCustomFileArray = exports.isCustomFile = exports.serializeForm = exports.parseFormData = exports.createFormData = exports.createControlledFormData = exports.convertIntoFormData = exports.naturalSortForString = exports.naturalSort = exports.compareSorter = exports.compareNaturally = exports.splitArray = exports.rotateArray = exports.removeDuplicatesFromArray = exports.removeDuplicates = exports.moveArrayElement = exports.getMissingElements = void 0;
7
- exports.isObjectEmpty = exports.isObject = exports.isNotEmptyObject = exports.isMethodDescriptor = exports.isMethod = exports.isMap = exports.isJSONObject = exports.isJSON = exports.isFunction = exports.isError = exports.isEmptyObjectGuard = exports.isEmptyObject = exports.isDate = exports.isBigInt = exports.isArrayWithLength = exports.isArrayOfType = exports.isArray = exports.doesReturnPromise = exports.isUndefined = exports.isTruthy = exports.isSymbol = exports.isString = exports.isPrimitive = exports.isPositiveInteger = exports.isNumber = exports.isNull = exports.isNonEmptyString = exports.isInteger = exports.isFalsy = exports.isBoolean = exports.throttleAction = exports.isDeepEqual = exports.getStaticMethodsCount = exports.getStaticMethodNames = exports.getInstanceMethodsCount = exports.getInstanceMethodNames = exports.getClassDetails = exports.debounceAction = exports.countStaticMethods = exports.countInstanceMethods = exports.convertArrayToString = exports.saveToSessionStorage = exports.saveToLocalStorage = exports.removeFromSessionStorage = exports.removeFromLocalStorage = exports.getFromSessionStorage = exports.getFromLocalStorage = exports.toggleFullScreen = exports.smoothScrollTo = exports.copyToClipboard = void 0;
8
- exports.isValidURL = exports.isValidEmail = exports.isUUID = exports.isURL = exports.isPhoneNumber = exports.isNumericString = exports.isNodeEnvironment = exports.isNodeENV = exports.isNode = exports.isIPAddress = exports.isExpectedNodeENV = exports.isEnvironment = exports.isEmailArray = exports.isEmail = exports.isDateString = exports.isBrowser = exports.isBase64 = exports.isValidSet = exports.isValidObject = exports.isValidMap = exports.isValidJSON = exports.isValidArray = exports.isSet = exports.isReturningPromise = exports.isRegularExpression = exports.isRegExp = exports.isPromise = exports.isObjectWithKeys = void 0;
6
+ exports.getQueryParams = exports.generateQueryParams = exports.formatQueryParams = exports.createQueryParams = exports.remapObjectFields = exports.remapFields = exports.pickObjectFieldsByCondition = exports.pickObjectFields = exports.pickFieldsByCondition = exports.pickFields = exports.convertObjectValues = exports.sanitizeData = exports.parseStringifiedValues = exports.parseStringifiedPrimitives = exports.parseStringifiedObjectValues = exports.parsePrimitives = exports.parsePrimitiveData = exports.parseObjectValues = exports.parseJsonToObject = exports.mergeObjects = exports.mergeAndFlattenObjects = exports.flattenObjectKeyValue = exports.flattenObjectDotNotation = exports.extractUpdatedFields = exports.extractUpdatedAndNewFields = exports.extractNewFields = exports.countObjectFields = exports.cloneObject = exports.isValidFormData = exports.isOriginFileObj = exports.isFileUpload = exports.isFileList = exports.isFileArray = exports.isCustomFileArray = exports.isCustomFile = exports.serializeForm = exports.parseFormData = exports.createFormData = exports.createControlledFormData = exports.convertIntoFormData = exports.naturalSortForString = exports.naturalSort = exports.compareSorter = exports.compareNaturally = exports.splitArray = exports.rotateArray = exports.removeDuplicatesFromArray = exports.removeDuplicates = exports.moveArrayElement = exports.getMissingElements = void 0;
7
+ exports.isFunction = exports.isError = exports.isEmptyObjectGuard = exports.isEmptyObject = exports.isDate = exports.isBigInt = exports.isArrayWithLength = exports.isArrayOfType = exports.isArray = exports.doesReturnPromise = exports.isUndefined = exports.isTruthy = exports.isSymbol = exports.isString = exports.isPrimitive = exports.isPositiveInteger = exports.isNumber = exports.isNull = exports.isNonEmptyString = exports.isInteger = exports.isFalsy = exports.isBoolean = exports.throttleAction = exports.parsePrimitivesDeep = exports.parseJsonDeep = exports.parseJSON = exports.isDeepEqual = exports.getStaticMethodsCount = exports.getStaticMethodNames = exports.getInstanceMethodsCount = exports.getInstanceMethodNames = exports.getClassDetails = exports.deepParsePrimitives = exports.debounceAction = exports.countStaticMethods = exports.countInstanceMethods = exports.convertArrayToString = exports.saveToSessionStorage = exports.saveToLocalStorage = exports.removeFromSessionStorage = exports.removeFromLocalStorage = exports.getFromSessionStorage = exports.getFromLocalStorage = exports.toggleFullScreen = exports.smoothScrollTo = exports.copyToClipboard = exports.updateQueryParam = exports.getQueryStringAsObject = exports.queryStringToObject = exports.parseQueryString = void 0;
8
+ exports.isValidURL = exports.isValidEmail = exports.isUUID = exports.isURL = exports.isPhoneNumber = exports.isNumericString = exports.isNodeEnvironment = exports.isNodeENV = exports.isNode = exports.isIPAddress = exports.isExpectedNodeENV = exports.isEnvironment = exports.isEmailArray = exports.isEmail = exports.isDateString = exports.isBrowser = exports.isBase64 = exports.isValidSet = exports.isValidObject = exports.isValidMap = exports.isValidJSON = exports.isValidArray = exports.isSet = exports.isReturningPromise = exports.isRegularExpression = exports.isRegExp = exports.isPromise = exports.isObjectWithKeys = exports.isObjectEmpty = exports.isObject = exports.isNotEmptyObject = exports.isMethodDescriptor = exports.isMethod = exports.isMap = exports.isJSONObject = exports.isJSON = void 0;
9
9
  // ! String Utilities
10
10
  var basics_1 = require("./string/basics");
11
11
  Object.defineProperty(exports, "capitalizeString", { enumerable: true, get: function () { return basics_1.capitalizeString; } });
@@ -34,12 +34,12 @@ Object.defineProperty(exports, "replaceAllInString", { enumerable: true, get: fu
34
34
  Object.defineProperty(exports, "reverseString", { enumerable: true, get: function () { return convert_1.reverseString; } });
35
35
  Object.defineProperty(exports, "slugifyString", { enumerable: true, get: function () { return convert_1.slugifyString; } });
36
36
  var utilities_1 = require("./string/utilities");
37
+ Object.defineProperty(exports, "countWords", { enumerable: true, get: function () { return utilities_1.countWords; } });
38
+ Object.defineProperty(exports, "countWordsInString", { enumerable: true, get: function () { return utilities_1.countWords; } });
37
39
  Object.defineProperty(exports, "extractNumbersFromString", { enumerable: true, get: function () { return utilities_1.extractNumbersFromString; } });
38
40
  Object.defineProperty(exports, "getLevenshteinDistance", { enumerable: true, get: function () { return utilities_1.getLevenshteinDistance; } });
39
41
  Object.defineProperty(exports, "levenshteinDistance", { enumerable: true, get: function () { return utilities_1.getLevenshteinDistance; } });
40
- Object.defineProperty(exports, "countWords", { enumerable: true, get: function () { return utilities_1.countWords; } });
41
42
  Object.defineProperty(exports, "wordCount", { enumerable: true, get: function () { return utilities_1.countWords; } });
42
- Object.defineProperty(exports, "countWordsInString", { enumerable: true, get: function () { return utilities_1.countWords; } });
43
43
  // ! Number Utilities
44
44
  var basics_2 = require("./number/basics");
45
45
  Object.defineProperty(exports, "calculateAverage", { enumerable: true, get: function () { return basics_2.getAverage; } });
@@ -225,6 +225,7 @@ Object.defineProperty(exports, "flattenObjectDotNotation", { enumerable: true, g
225
225
  Object.defineProperty(exports, "flattenObjectKeyValue", { enumerable: true, get: function () { return objectify_1.flattenObjectKeyValue; } });
226
226
  Object.defineProperty(exports, "mergeAndFlattenObjects", { enumerable: true, get: function () { return objectify_1.mergeAndFlattenObjects; } });
227
227
  Object.defineProperty(exports, "mergeObjects", { enumerable: true, get: function () { return objectify_1.mergeObjects; } });
228
+ Object.defineProperty(exports, "parseJsonToObject", { enumerable: true, get: function () { return objectify_1.parseJsonToObject; } });
228
229
  var sanitize_1 = require("./object/sanitize");
229
230
  Object.defineProperty(exports, "parseObjectValues", { enumerable: true, get: function () { return sanitize_1.parseObjectValues; } });
230
231
  Object.defineProperty(exports, "parsePrimitiveData", { enumerable: true, get: function () { return sanitize_1.parseObjectValues; } });
@@ -247,6 +248,9 @@ Object.defineProperty(exports, "createQueryParams", { enumerable: true, get: fun
247
248
  Object.defineProperty(exports, "formatQueryParams", { enumerable: true, get: function () { return query_1.generateQueryParams; } });
248
249
  Object.defineProperty(exports, "generateQueryParams", { enumerable: true, get: function () { return query_1.generateQueryParams; } });
249
250
  Object.defineProperty(exports, "getQueryParams", { enumerable: true, get: function () { return query_1.getQueryParams; } });
251
+ Object.defineProperty(exports, "parseQueryString", { enumerable: true, get: function () { return query_1.parseQueryString; } });
252
+ Object.defineProperty(exports, "queryStringToObject", { enumerable: true, get: function () { return query_1.parseQueryString; } });
253
+ Object.defineProperty(exports, "getQueryStringAsObject", { enumerable: true, get: function () { return query_1.parseQueryString; } });
250
254
  Object.defineProperty(exports, "updateQueryParam", { enumerable: true, get: function () { return query_1.updateQueryParam; } });
251
255
  var utils_3 = require("./dom/utils");
252
256
  Object.defineProperty(exports, "copyToClipboard", { enumerable: true, get: function () { return utils_3.copyToClipboard; } });
@@ -265,12 +269,16 @@ Object.defineProperty(exports, "convertArrayToString", { enumerable: true, get:
265
269
  Object.defineProperty(exports, "countInstanceMethods", { enumerable: true, get: function () { return utils_4.countInstanceMethods; } });
266
270
  Object.defineProperty(exports, "countStaticMethods", { enumerable: true, get: function () { return utils_4.countStaticMethods; } });
267
271
  Object.defineProperty(exports, "debounceAction", { enumerable: true, get: function () { return utils_4.debounceAction; } });
272
+ Object.defineProperty(exports, "deepParsePrimitives", { enumerable: true, get: function () { return utils_4.deepParsePrimitives; } });
268
273
  Object.defineProperty(exports, "getClassDetails", { enumerable: true, get: function () { return utils_4.getClassDetails; } });
269
274
  Object.defineProperty(exports, "getInstanceMethodNames", { enumerable: true, get: function () { return utils_4.getInstanceMethodNames; } });
270
275
  Object.defineProperty(exports, "getInstanceMethodsCount", { enumerable: true, get: function () { return utils_4.countInstanceMethods; } });
271
276
  Object.defineProperty(exports, "getStaticMethodNames", { enumerable: true, get: function () { return utils_4.getStaticMethodNames; } });
272
277
  Object.defineProperty(exports, "getStaticMethodsCount", { enumerable: true, get: function () { return utils_4.countStaticMethods; } });
273
278
  Object.defineProperty(exports, "isDeepEqual", { enumerable: true, get: function () { return utils_4.isDeepEqual; } });
279
+ Object.defineProperty(exports, "parseJSON", { enumerable: true, get: function () { return utils_4.parseJSON; } });
280
+ Object.defineProperty(exports, "parseJsonDeep", { enumerable: true, get: function () { return utils_4.parseJSON; } });
281
+ Object.defineProperty(exports, "parsePrimitivesDeep", { enumerable: true, get: function () { return utils_4.deepParsePrimitives; } });
274
282
  Object.defineProperty(exports, "throttleAction", { enumerable: true, get: function () { return utils_4.throttleAction; } });
275
283
  // ! Primitive Type Guards
276
284
  var primitives_1 = require("./guards/primitives");
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractUpdatedAndNewFields = exports.extractNewFields = exports.extractUpdatedFields = exports.flattenObjectDotNotation = exports.flattenObjectKeyValue = exports.mergeAndFlattenObjects = exports.mergeObjects = void 0;
3
+ exports.parseJsonToObject = exports.extractUpdatedAndNewFields = exports.extractNewFields = exports.extractUpdatedFields = exports.flattenObjectDotNotation = exports.flattenObjectKeyValue = exports.mergeAndFlattenObjects = exports.mergeObjects = void 0;
4
4
  const non_primitives_1 = require("../guards/non-primitives");
5
5
  const utils_1 = require("../utils");
6
+ const sanitize_1 = require("./sanitize");
6
7
  /**
7
8
  * * Deeply merge two or more objects using `Map`.
8
9
  *
@@ -213,3 +214,25 @@ const extractUpdatedAndNewFields = (baseObject, updatedObject) => {
213
214
  return { ...updatedFields, ...newFields };
214
215
  };
215
216
  exports.extractUpdatedAndNewFields = extractUpdatedAndNewFields;
217
+ /**
218
+ * * Safely parses a JSON string into an object.
219
+ *
220
+ * *Optionally converts stringified primitive values inside the object (e.g., `"0"` → `0`, `"true"` → `true`, `"null"` → `null`).*
221
+ *
222
+ * @param value - The JSON string to parse.
223
+ * @param parsePrimitives - Whether to convert stringified primitives into real values (default: `true`).
224
+ * @returns A parsed object with primitive conversions, or an empty object on failure or if the root is not a valid object.
225
+ */
226
+ const parseJsonToObject = (value, parsePrimitives = true) => {
227
+ try {
228
+ const data = JSON.parse(value);
229
+ if (!(0, non_primitives_1.isObject)(data)) {
230
+ return {};
231
+ }
232
+ return parsePrimitives ? (0, sanitize_1.parseObjectValues)(data) : data;
233
+ }
234
+ catch {
235
+ return {};
236
+ }
237
+ };
238
+ exports.parseJsonToObject = parseJsonToObject;
@@ -105,6 +105,12 @@ function parseObjectValues(object) {
105
105
  else if (!isNaN(Number(value))) {
106
106
  parsedBody[key] = Number(value);
107
107
  }
108
+ else if (value === 'undefined') {
109
+ parsedBody[key] = undefined;
110
+ }
111
+ else if (value === 'null') {
112
+ parsedBody[key] = null;
113
+ }
108
114
  else {
109
115
  parsedBody[key] = value;
110
116
  }