@valkyriestudios/utils 12.21.0 → 12.23.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/README.md +55 -2
- package/formdata/toObject.d.ts +12 -1
- package/formdata/toObject.js +46 -10
- package/hash/fnv1A.d.ts +2 -0
- package/hash/fnv1A.js +4 -2
- package/index.d.ts +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -787,7 +787,7 @@ isFormData(new FormData()); // TRUE
|
|
|
787
787
|
isFormData({hi: 'there'}); // FALSE
|
|
788
788
|
```
|
|
789
789
|
|
|
790
|
-
### formdata/toObject(val:FormData)
|
|
790
|
+
### formdata/toObject(val:FormData, {raw?:string[]|true;single?:string[]} = {})
|
|
791
791
|
Converts an instance of FormData to an object
|
|
792
792
|
```typescript
|
|
793
793
|
import toObject from '@valkyriestudios/utils/formdata/toObject';
|
|
@@ -800,6 +800,59 @@ form.append('emptyField', '');
|
|
|
800
800
|
toObject(form); // {name: 'Alice', hobbies: ['reading', 'writing'], emptyField: ''}
|
|
801
801
|
```
|
|
802
802
|
|
|
803
|
+
Automatically converts strings to numbers and booleans, and nests objects/arrays based on key structures:
|
|
804
|
+
```typescript
|
|
805
|
+
const form = new FormData();
|
|
806
|
+
form.append('user[0].name', 'Alice');
|
|
807
|
+
form.append('user[1].age', '25');
|
|
808
|
+
form.append('enabled', 'false');
|
|
809
|
+
form.append('config.isGood', 'true');
|
|
810
|
+
form.append('config.amount', ' 50 ');
|
|
811
|
+
|
|
812
|
+
toObject(form); /* {
|
|
813
|
+
user: [
|
|
814
|
+
{name: 'Alice'},
|
|
815
|
+
{age: 25},
|
|
816
|
+
],
|
|
817
|
+
enabled: false,
|
|
818
|
+
config: {
|
|
819
|
+
isGood: true,
|
|
820
|
+
amount: 50,
|
|
821
|
+
},
|
|
822
|
+
} */
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
Allows blacklisting keys that should not be normalized into numbers/booleans but should remain as they are:
|
|
826
|
+
```typescript
|
|
827
|
+
const form = new FormData();
|
|
828
|
+
form.append('pincode', '0123');
|
|
829
|
+
form.append('enabled', 'false');
|
|
830
|
+
form.append('config.isGood', 'true');
|
|
831
|
+
form.append('config.amount', ' 50 ');
|
|
832
|
+
|
|
833
|
+
toObject(form, {raw: ['pincode']}); /* {
|
|
834
|
+
pincode: '0123',
|
|
835
|
+
enabled: false,
|
|
836
|
+
config: {
|
|
837
|
+
isGood: true,
|
|
838
|
+
amount: 50,
|
|
839
|
+
},
|
|
840
|
+
} */
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
Take Note: Set raw to `true` to do no normalization
|
|
844
|
+
|
|
845
|
+
Allows passing a 'single' list that tells the system to NEVER turn a particular value into an array of values:
|
|
846
|
+
```typescript
|
|
847
|
+
const formData = new FormData();
|
|
848
|
+
formData.append('status', 'active');
|
|
849
|
+
formData.append('status', 'inactive');
|
|
850
|
+
formData.append('action', 'save');
|
|
851
|
+
formData.append('action', 'reset');
|
|
852
|
+
|
|
853
|
+
toObject(formData, { single: ['status', 'action'] }) /* {status: 'inactive', action: 'reset'} */
|
|
854
|
+
```
|
|
855
|
+
|
|
803
856
|
### hash/guid()
|
|
804
857
|
Generate a unique identifier (guid) according to RFC4122
|
|
805
858
|
```typescript
|
|
@@ -1199,4 +1252,4 @@ humanizeNumber(47328748923747923479); // '47,328.75q'
|
|
|
1199
1252
|
|
|
1200
1253
|
## Contributors
|
|
1201
1254
|
- [Peter Vermeulen](https://www.linkedin.com/in/petervermeulen1/)
|
|
1202
|
-
- [Xander Berkein](https://github.com/xanderberkein)
|
|
1255
|
+
- [Xander Berkein](https://github.com/xanderberkein)
|
package/formdata/toObject.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
type toObjectConfig = {
|
|
2
|
+
/**
|
|
3
|
+
* Pass array of keys that should not be normalized into number/bool when seen
|
|
4
|
+
*/
|
|
5
|
+
raw?: string[] | true;
|
|
6
|
+
/**
|
|
7
|
+
* Pass array of keys that should only have a single value (e.g., 'action')
|
|
8
|
+
*/
|
|
9
|
+
single?: string[];
|
|
10
|
+
};
|
|
1
11
|
/**
|
|
2
12
|
* Converts a FormData instance to a json object
|
|
3
13
|
* Eg:
|
|
@@ -11,6 +21,7 @@
|
|
|
11
21
|
* {name: 'Alice', hobbies: ['reading', 'writing'], emptyField: ''}
|
|
12
22
|
*
|
|
13
23
|
* @param {FormData} val - FormData instance to convert to an object
|
|
24
|
+
* @param {}
|
|
14
25
|
*/
|
|
15
|
-
declare function toObject<T extends Record<string, unknown>>(form: FormData): T;
|
|
26
|
+
declare function toObject<T extends Record<string, unknown>>(form: FormData, config?: toObjectConfig): T;
|
|
16
27
|
export { toObject, toObject as default };
|
package/formdata/toObject.js
CHANGED
|
@@ -2,22 +2,58 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toObject = toObject;
|
|
4
4
|
exports.default = toObject;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
const RGX_CLOSE = /\]/g;
|
|
6
|
+
function assignValue(acc, rawkey, value, single) {
|
|
7
|
+
let cursor = acc;
|
|
8
|
+
const keys = rawkey.replace(RGX_CLOSE, '').split(/\[|\./);
|
|
9
|
+
for (let i = 0; i < keys.length; i++) {
|
|
10
|
+
const key = keys[i];
|
|
11
|
+
if (i === keys.length - 1) {
|
|
12
|
+
if (cursor[key] !== undefined && (!single || !single.has(key))) {
|
|
13
|
+
if (Array.isArray(cursor[key])) {
|
|
14
|
+
cursor[key].push(value);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
cursor[key] = [cursor[key], value];
|
|
18
|
+
}
|
|
13
19
|
}
|
|
14
20
|
else {
|
|
15
|
-
|
|
21
|
+
cursor[key] = value;
|
|
16
22
|
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(cursor)) {
|
|
26
|
+
const index = Number(key);
|
|
27
|
+
if (!cursor[index])
|
|
28
|
+
cursor[index] = isNaN(Number(keys[i + 1])) ? {} : [];
|
|
29
|
+
cursor = cursor[index];
|
|
17
30
|
}
|
|
18
31
|
else {
|
|
19
|
-
|
|
32
|
+
if (!cursor[key])
|
|
33
|
+
cursor[key] = isNaN(Number(keys[i + 1])) ? {} : [];
|
|
34
|
+
cursor = cursor[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function toObject(form, config) {
|
|
39
|
+
if (!(form instanceof FormData))
|
|
40
|
+
throw new Error('formdata/toObject: Value is not an instance of FormData');
|
|
41
|
+
const set = config?.raw === true ? true : new Set(Array.isArray(config?.raw) ? config?.raw : []);
|
|
42
|
+
const single = Array.isArray(config?.single) && config?.single.length ? new Set(config.single) : null;
|
|
43
|
+
const acc = {};
|
|
44
|
+
form.forEach((value, key) => {
|
|
45
|
+
let normalizedValue = value;
|
|
46
|
+
if (set !== true && typeof value === 'string' && !set.has(key)) {
|
|
47
|
+
const lower = value.toLowerCase();
|
|
48
|
+
normalizedValue = (lower === 'true'
|
|
49
|
+
? true
|
|
50
|
+
: lower === 'false'
|
|
51
|
+
? false
|
|
52
|
+
: !isNaN(Number(value)) && value.trim() !== ''
|
|
53
|
+
? Number(value)
|
|
54
|
+
: value);
|
|
20
55
|
}
|
|
56
|
+
assignValue(acc, key, normalizedValue, single);
|
|
21
57
|
});
|
|
22
58
|
return acc;
|
|
23
59
|
}
|
package/hash/fnv1A.d.ts
CHANGED
package/hash/fnv1A.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FNV_64 = exports.FNV_32 = void 0;
|
|
3
4
|
exports.fnv1A = fnv1A;
|
|
4
5
|
exports.default = fnv1A;
|
|
5
|
-
|
|
6
|
+
exports.FNV_32 = 2166136261;
|
|
7
|
+
exports.FNV_64 = 1099511628211;
|
|
6
8
|
const REPL_NAN = 'nan';
|
|
7
9
|
const REPL_TRUE = 'true';
|
|
8
10
|
const REPL_FALSE = 'false';
|
|
9
11
|
const REPL_UNDEF = 'undefined';
|
|
10
12
|
const REPL_NULL = 'null';
|
|
11
|
-
function fnv1A(data, offset = FNV_32) {
|
|
13
|
+
function fnv1A(data, offset = exports.FNV_32) {
|
|
12
14
|
let hash = offset;
|
|
13
15
|
let sanitized;
|
|
14
16
|
switch (typeof data) {
|
package/index.d.ts
CHANGED
|
@@ -226,7 +226,11 @@ declare module "formdata/is" {
|
|
|
226
226
|
export { isFormData, isFormData as default };
|
|
227
227
|
}
|
|
228
228
|
declare module "formdata/toObject" {
|
|
229
|
-
|
|
229
|
+
type toObjectConfig = {
|
|
230
|
+
raw?: string[] | true;
|
|
231
|
+
single?: string[];
|
|
232
|
+
};
|
|
233
|
+
function toObject<T extends Record<string, unknown>>(form: FormData, config?: toObjectConfig): T;
|
|
230
234
|
export { toObject, toObject as default };
|
|
231
235
|
}
|
|
232
236
|
declare module "formdata/index" {
|
|
@@ -566,6 +570,8 @@ declare module "deep/index" {
|
|
|
566
570
|
export { deepFreeze as freeze, deepFreeze, deepGet as get, deepGet, deepSeal as seal, deepSeal, deepSet as set, deepSet };
|
|
567
571
|
}
|
|
568
572
|
declare module "hash/fnv1A" {
|
|
573
|
+
export const FNV_32 = 2166136261;
|
|
574
|
+
export const FNV_64 = 1099511628211;
|
|
569
575
|
function fnv1A(data: unknown, offset?: number): number;
|
|
570
576
|
export { fnv1A, fnv1A as default };
|
|
571
577
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "name": "@valkyriestudios/utils", "version": "12.
|
|
1
|
+
{ "name": "@valkyriestudios/utils", "version": "12.23.0", "description": "A collection of single-function utilities for common tasks", "author": { "name": "Peter Vermeulen", "url": "https://www.linkedin.com/in/petervermeulen1/" }, "keywords": [ "utility", "library", "javascript", "js", "node", "bun" ], "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/ValkyrieStudios/utils.git" }, "bugs": { "url": "https://github.com/ValkyrieStudios/utils/issues" }, "homepage": "https://github.com/ValkyrieStudios/utils#readme", "types": "index.d.ts" }
|