nhb-toolbox 2.3.8 → 2.4.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.
@@ -1,10 +1,11 @@
1
+ import type { LooseObject } from '../object/types';
1
2
  /**
2
3
  * * Utility to convert object into FormData.
3
4
  *
4
5
  * @param data Data to convert into FormData.
5
6
  * @returns Converted FormData.
6
7
  */
7
- export declare const convertIntoFormData: <T extends object>(data: T) => FormData;
8
+ export declare const convertIntoFormData: <T extends LooseObject>(data: T) => FormData;
8
9
  /**
9
10
  * * Check if a formdata object is empty.
10
11
  *
@@ -1 +1 @@
1
- {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/form/convert.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,QAAQ,CAAC,KAAG,QAY/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,SAAU,QAAQ,KAAG,OAQhD,CAAC"}
1
+ {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/form/convert.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,WAAW,QAClD,CAAC,KACL,QAYF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,SAAU,QAAQ,KAAG,OAQhD,CAAC"}
@@ -1,12 +1,12 @@
1
- import type { LooseObject } from '../object/types';
1
+ import type { GenericObject } from '../object/types';
2
2
  import type { FormDataConfigs } from './types';
3
3
  /**
4
- * * Utility to convert object into FormData in a controlled way.
4
+ * Utility to convert object into FormData in a controlled way.
5
5
  *
6
6
  * @param data - The source object to control and convert to FormData.
7
7
  * @param configs - Configuration options to control the formData.
8
8
  *
9
9
  * @returns FormData instance containing the sanitized and transformed data
10
10
  */
11
- export declare const createControlledFormData: <T extends LooseObject>(data: T, configs?: FormDataConfigs<T>) => FormData;
11
+ export declare const createControlledFormData: <T extends GenericObject>(data: T, configs?: FormDataConfigs<T>) => FormData;
12
12
  //# sourceMappingURL=transform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/form/transform.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,WAAW,QACvD,CAAC,YACG,eAAe,CAAC,CAAC,CAAC,KAC1B,QAkDF,CAAC"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/form/transform.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEX,aAAa,EAEb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,aAAa,QACzD,CAAC,YACG,eAAe,CAAC,CAAC,CAAC,KAC1B,QAqFF,CAAC"}
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createControlledFormData = void 0;
4
- const basics_1 = require("../object/basics");
4
+ const basics_1 = require("../array/basics");
5
+ const basics_2 = require("../object/basics");
5
6
  /**
6
- * * Utility to convert object into FormData in a controlled way.
7
+ * Utility to convert object into FormData in a controlled way.
7
8
  *
8
9
  * @param data - The source object to control and convert to FormData.
9
10
  * @param configs - Configuration options to control the formData.
@@ -13,49 +14,71 @@ const basics_1 = require("../object/basics");
13
14
  const createControlledFormData = (data, configs) => {
14
15
  const formData = new FormData();
15
16
  const addToFormData = (key, value) => {
16
- if (value instanceof File) {
17
- formData.append(key, value);
17
+ const transformedKey = (configs?.lowerCaseKeys === '*' ||
18
+ configs?.lowerCaseKeys?.includes(key)) ?
19
+ key.toLowerCase()
20
+ : key;
21
+ if (!(0, basics_1.isValidEmptyArray)(value) && value[0]?.originFileObj) {
22
+ formData.append(transformedKey, value[0].originFileObj);
18
23
  }
19
24
  else if (Array.isArray(value)) {
20
25
  value.forEach((item, index) => {
21
- addToFormData(`${key}[${index}]`, item);
26
+ addToFormData(`${transformedKey}[${index}]`, item);
22
27
  });
23
28
  }
24
- else if (typeof value === 'object' && !(0, basics_1.isEmptyObject)(value)) {
29
+ else if (typeof value === 'object' &&
30
+ value !== null &&
31
+ !(0, basics_2.isEmptyObject)(value)) {
32
+ // Handle nested object by converting it into a string representation like 'name.first'
25
33
  Object.entries(value).forEach(([nestedKey, nestedValue]) => {
26
34
  addToFormData(`${key}.${nestedKey}`, nestedValue);
27
35
  });
28
36
  }
29
37
  else {
30
- formData.append(key, value);
38
+ const isRequired = configs?.requiredKeys === '*' ||
39
+ configs?.requiredKeys?.includes(key);
40
+ const isNotNullish = value != null && value !== '';
41
+ if (isNotNullish || isRequired) {
42
+ formData.append(transformedKey, value);
43
+ }
31
44
  }
32
45
  };
33
- const isPathPreserved = (key) => {
34
- return configs?.preservePaths?.some((path) => key.startsWith(path));
46
+ // Helper function to check if a key matches a preserved path
47
+ const isPathPreserved = (fullKey) => {
48
+ if (Array.isArray(configs?.preservePaths))
49
+ return configs?.preservePaths?.some((path) => fullKey === path || fullKey.startsWith(`${path}.`));
50
+ return configs?.preservePaths === '*';
35
51
  };
36
- Object.entries(data).forEach(([key, value]) => {
37
- // 1. Skip keys that are in ignoreKeys
38
- if (configs?.ignoreKeys?.includes(key))
39
- return;
40
- // 2. Trim string values if trimStrings is enabled
41
- if (configs?.trimStrings && typeof value === 'string') {
42
- value = value.trim();
43
- }
44
- // 3. Ensure requiredKeys are included even if falsy
45
- if (configs?.requiredKeys?.includes(key) && value == null) {
46
- value = ''; // Make sure it's an empty string for falsy values
47
- }
48
- // 4. Check preservePaths, if true, preserve values for nested paths
49
- if (isPathPreserved(key)) {
50
- addToFormData(key, value);
51
- }
52
- else {
53
- const transformedKey = configs?.lowerCaseKeys?.includes(key) ?
54
- key.toLowerCase()
55
- : key;
56
- addToFormData(transformedKey, value);
57
- }
58
- });
52
+ const processObject = (obj, parentKey = '') => {
53
+ Object.entries(obj).forEach(([key, value]) => {
54
+ const fullKey = (parentKey ?
55
+ `${parentKey}.${key}`
56
+ : key);
57
+ // Skip keys that are in ignoreKeys
58
+ if (configs?.ignoreKeys?.includes(fullKey))
59
+ return;
60
+ // Trim string values if trimStrings is enabled
61
+ if (configs?.trimStrings && typeof value === 'string') {
62
+ value = value.trim();
63
+ }
64
+ // Check if this key is preserved
65
+ if (isPathPreserved(fullKey)) {
66
+ // If it's a preserved path, we need to append the value directly as the key
67
+ addToFormData(fullKey, value);
68
+ }
69
+ else if (typeof value === 'object' &&
70
+ !Array.isArray(value) &&
71
+ value != null) {
72
+ // Process nested objects
73
+ processObject(value, key);
74
+ }
75
+ else {
76
+ // For other cases, just append as key-value
77
+ addToFormData(key, value);
78
+ }
79
+ });
80
+ };
81
+ processObject(data);
59
82
  return formData;
60
83
  };
61
84
  exports.createControlledFormData = createControlledFormData;
@@ -1,8 +1,14 @@
1
+ import type { DotNotationKey } from '../object/types';
1
2
  export interface FormDataConfigs<T> {
2
- ignoreKeys?: (keyof T)[];
3
- requiredKeys?: (keyof T)[];
4
- lowerCaseKeys?: (keyof T)[];
5
- preservePaths?: string[];
3
+ /** - Keys to exclude from processing. Ignored keys are ignored even if they're in other options */
4
+ ignoreKeys?: DotNotationKey<T>[];
5
+ /** - Keys to preserve even if falsy. `*` to include all keys */
6
+ requiredKeys?: '*' | DotNotationKey<T>[];
7
+ /** - Keys to convert to lowercase. `*` to include all keys */
8
+ lowerCaseKeys?: '*' | DotNotationKey<T>[];
9
+ /** - Dot-notation paths to preserve (e.g., 'user.settings.theme'). `*` to include all keys */
10
+ preservePaths?: '*' | DotNotationKey<T>[];
11
+ /** - Whether to trim string values */
6
12
  trimStrings?: boolean;
7
13
  }
8
14
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/form/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe,CAAC,CAAC;IAEjC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IAEzB,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IAE3B,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IAE5B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/form/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,eAAe,CAAC,CAAC;IACjC,mGAAmG;IACnG,UAAU,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IACjC,gEAAgE;IAChE,YAAY,CAAC,EAAE,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,+DAA+D;IAC/D,aAAa,CAAC,EAAE,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,8FAA8F;IAC9F,aAAa,CAAC,EAAE,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,sCAAsC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"basics.d.ts","sourceRoot":"","sources":["../../src/object/basics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,WAAW,WAChD,CAAC,KACP,MAkCF,CAAC;AACF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,aAAa,OAAO,CAAC,KAAG,CAE7D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,aAAa,OAAO,CAAC,KAAG,OAE/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,aAAa,OAAO,CAAC,KAAG,MAEnE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,SAAU,OAAO,KAAG,OAExC,CAAC"}
1
+ {"version":3,"file":"basics.d.ts","sourceRoot":"","sources":["../../src/object/basics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,WAAW,WAChD,CAAC,KACP,MAkCF,CAAC;AACF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,aAAa,OAAO,CAAC,KAAG,CAE7D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,aAAa,OAAO,CAAC,KAAG,OAI/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,aAAa,OAAO,CAAC,KAAG,MAInE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,SAAU,OAAO,KAAG,OAExC,CAAC"}
@@ -52,7 +52,9 @@ exports.cloneObject = cloneObject;
52
52
  * @returns Whether the object is empty.
53
53
  */
54
54
  const isEmptyObject = (obj) => {
55
- return (0, exports.countObjectFields)(obj) === 0;
55
+ if (obj != null)
56
+ return (0, exports.countObjectFields)(obj) === 0;
57
+ return false;
56
58
  };
57
59
  exports.isEmptyObject = isEmptyObject;
58
60
  /**
@@ -62,7 +64,9 @@ exports.isEmptyObject = isEmptyObject;
62
64
  * @returns Number of fields in the object.
63
65
  */
64
66
  const countObjectFields = (obj) => {
65
- return Object.keys(obj).length;
67
+ if (obj != null)
68
+ return Object.keys(obj).length;
69
+ return 0;
66
70
  };
67
71
  exports.countObjectFields = countObjectFields;
68
72
  /**
@@ -44,7 +44,7 @@ function convertStringCase(string, format) {
44
44
  }
45
45
  return (startSymbol +
46
46
  coreWord.charAt(0).toUpperCase() +
47
- coreWord.slice(1) +
47
+ coreWord.slice(1).toLowerCase() +
48
48
  endSymbol);
49
49
  })
50
50
  .join(' ');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nhb-toolbox",
3
- "version": "2.3.8",
3
+ "version": "2.4.0",
4
4
  "description": "A versatile collection of smart, efficient, and reusable utility functions for everyday development needs.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",