@pixpilot/object 2.3.0 → 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.
- package/README.md +5 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/keys-to-camel-case.cjs +30 -4
- package/dist/keys-to-camel-case.d.cts +5 -2
- package/dist/keys-to-camel-case.d.ts +5 -2
- package/dist/keys-to-camel-case.js +30 -4
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -25,6 +25,10 @@ const obj = { user_name: 'john', user_details: { first_name: 'John' } };
|
|
|
25
25
|
const camelCaseObj = keysToCamelCase(obj);
|
|
26
26
|
// { userName: 'john', userDetails: { firstName: 'John' } }
|
|
27
27
|
|
|
28
|
+
const guidSafeObj = keysToCamelCase(obj, {
|
|
29
|
+
shouldConvert: (key) => key !== 'legacy_key',
|
|
30
|
+
});
|
|
31
|
+
|
|
28
32
|
// Manipulate objects
|
|
29
33
|
const picked = pick({ a: 1, b: 2, c: 3 }, ['a', 'c']); // { a: 1, c: 3 }
|
|
30
34
|
const omitted = omit({ a: 1, b: 2, c: 3 }, ['b']); // { a: 1, c: 3 }
|
|
@@ -48,7 +52,7 @@ if (isObject(value)) {
|
|
|
48
52
|
|
|
49
53
|
### Key Transformation
|
|
50
54
|
|
|
51
|
-
- `keysToCamelCase<T>(obj: T): KeysToCamelCase<T>` - Convert
|
|
55
|
+
- `keysToCamelCase<T>(obj: T, options?: { shouldConvert?: (key: string) => boolean }): KeysToCamelCase<T>` - Convert keys to camelCase, except GUID keys and keys rejected by `shouldConvert`
|
|
52
56
|
- `keysToSnakeCase<T>(obj: T): KeysToSnakeCase<T>` - Convert all keys to snake_case
|
|
53
57
|
|
|
54
58
|
### Object Manipulation
|
package/dist/index.d.cts
CHANGED
|
@@ -3,9 +3,9 @@ import { deepMerge, deepMergeMany } from "./deep-merge.cjs";
|
|
|
3
3
|
import { deleteObjectPropertyByPath as deleteProperty } from "./delete-object-property-by-path.cjs";
|
|
4
4
|
import { getObjectValueByPath as getProperty } from "./get-object-value-by-path.cjs";
|
|
5
5
|
import { hasObjectValueByPath as hasProperty } from "./has-object-value-by-path.cjs";
|
|
6
|
-
import { KeysToCamelCase, ToCamelCase, keysToCamelCase } from "./keys-to-camel-case.cjs";
|
|
6
|
+
import { KeysToCamelCase, KeysToCamelCaseOptions, ToCamelCase, keysToCamelCase } from "./keys-to-camel-case.cjs";
|
|
7
7
|
import { KeysToSnakeCase, ToSnakeCase, keysToSnakeCase } from "./keys-to-snake-case.cjs";
|
|
8
8
|
import { deepClone, deepEqual, deleteProperty as deleteProperty$1, escapePath, flatKeys, getProperty as getProperty$1, hasProperty as hasProperty$1, mapKeys, mapValues, omit, parsePath, pick, setProperty, stringifyPath, unflatten } from "./manipulation.cjs";
|
|
9
9
|
import { setObjectValueByPath } from "./set-object-value-by-path.cjs";
|
|
10
10
|
import { isEmptyObject, isObject, isPlainObject } from "./type-guards.cjs";
|
|
11
|
-
export { CleanOptions, KeysToCamelCase, KeysToSnakeCase, ToCamelCase, ToSnakeCase, cleanObject, deepClone, deepEqual, deepMerge, deepMergeMany, deleteProperty as deleteObjectPropertyByPath, deleteProperty$1 as deleteProperty, escapePath, flatKeys, getProperty as getObjectValueByPath, getProperty$1 as getProperty, hasProperty as hasObjectValueByPath, hasProperty$1 as hasProperty, isEmptyObject, isObject, isPlainObject, keysToCamelCase, keysToSnakeCase, mapKeys, mapValues, omit, parsePath, pick, setObjectValueByPath, setProperty, stringifyPath, unflatten };
|
|
11
|
+
export { CleanOptions, KeysToCamelCase, KeysToCamelCaseOptions, KeysToSnakeCase, ToCamelCase, ToSnakeCase, cleanObject, deepClone, deepEqual, deepMerge, deepMergeMany, deleteProperty as deleteObjectPropertyByPath, deleteProperty$1 as deleteProperty, escapePath, flatKeys, getProperty as getObjectValueByPath, getProperty$1 as getProperty, hasProperty as hasObjectValueByPath, hasProperty$1 as hasProperty, isEmptyObject, isObject, isPlainObject, keysToCamelCase, keysToSnakeCase, mapKeys, mapValues, omit, parsePath, pick, setObjectValueByPath, setProperty, stringifyPath, unflatten };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ import { deepMerge, deepMergeMany } from "./deep-merge.js";
|
|
|
3
3
|
import { deleteObjectPropertyByPath as deleteProperty } from "./delete-object-property-by-path.js";
|
|
4
4
|
import { getObjectValueByPath as getProperty } from "./get-object-value-by-path.js";
|
|
5
5
|
import { hasObjectValueByPath as hasProperty } from "./has-object-value-by-path.js";
|
|
6
|
-
import { KeysToCamelCase, ToCamelCase, keysToCamelCase } from "./keys-to-camel-case.js";
|
|
6
|
+
import { KeysToCamelCase, KeysToCamelCaseOptions, ToCamelCase, keysToCamelCase } from "./keys-to-camel-case.js";
|
|
7
7
|
import { KeysToSnakeCase, ToSnakeCase, keysToSnakeCase } from "./keys-to-snake-case.js";
|
|
8
8
|
import { deepClone, deepEqual, deleteProperty as deleteProperty$1, escapePath, flatKeys, getProperty as getProperty$1, hasProperty as hasProperty$1, mapKeys, mapValues, omit, parsePath, pick, setProperty, stringifyPath, unflatten } from "./manipulation.js";
|
|
9
9
|
import { setObjectValueByPath } from "./set-object-value-by-path.js";
|
|
10
10
|
import { isEmptyObject, isObject, isPlainObject } from "./type-guards.js";
|
|
11
|
-
export { CleanOptions, KeysToCamelCase, KeysToSnakeCase, ToCamelCase, ToSnakeCase, cleanObject, deepClone, deepEqual, deepMerge, deepMergeMany, deleteProperty as deleteObjectPropertyByPath, deleteProperty$1 as deleteProperty, escapePath, flatKeys, getProperty as getObjectValueByPath, getProperty$1 as getProperty, hasProperty as hasObjectValueByPath, hasProperty$1 as hasProperty, isEmptyObject, isObject, isPlainObject, keysToCamelCase, keysToSnakeCase, mapKeys, mapValues, omit, parsePath, pick, setObjectValueByPath, setProperty, stringifyPath, unflatten };
|
|
11
|
+
export { CleanOptions, KeysToCamelCase, KeysToCamelCaseOptions, KeysToSnakeCase, ToCamelCase, ToSnakeCase, cleanObject, deepClone, deepEqual, deepMerge, deepMergeMany, deleteProperty as deleteObjectPropertyByPath, deleteProperty$1 as deleteProperty, escapePath, flatKeys, getProperty as getObjectValueByPath, getProperty$1 as getProperty, hasProperty as hasObjectValueByPath, hasProperty$1 as hasProperty, isEmptyObject, isObject, isPlainObject, keysToCamelCase, keysToSnakeCase, mapKeys, mapValues, omit, parsePath, pick, setObjectValueByPath, setProperty, stringifyPath, unflatten };
|
|
@@ -3,13 +3,39 @@ let __pixpilot_string = require("@pixpilot/string");
|
|
|
3
3
|
__pixpilot_string = require_rolldown_runtime.__toESM(__pixpilot_string);
|
|
4
4
|
|
|
5
5
|
//#region src/keys-to-camel-case.ts
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const FIRST_CHARACTER_INDEX = 0;
|
|
7
|
+
const GUID_LENGTH = 36;
|
|
8
|
+
const GUID_SEPARATOR_CODE = "-".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
9
|
+
const GUID_SEPARATOR_ONE_INDEX = 8;
|
|
10
|
+
const GUID_SEPARATOR_TWO_INDEX = 13;
|
|
11
|
+
const GUID_SEPARATOR_THREE_INDEX = 18;
|
|
12
|
+
const GUID_SEPARATOR_FOUR_INDEX = 23;
|
|
13
|
+
const ZERO_CODE = "0".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
14
|
+
const NINE_CODE = "9".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
15
|
+
const UPPERCASE_A_CODE = "A".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
16
|
+
const UPPERCASE_F_CODE = "F".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
17
|
+
const LOWERCASE_A_CODE = "a".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
18
|
+
const LOWERCASE_F_CODE = "f".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
19
|
+
function isHexCode(charCode) {
|
|
20
|
+
return charCode >= ZERO_CODE && charCode <= NINE_CODE || charCode >= UPPERCASE_A_CODE && charCode <= UPPERCASE_F_CODE || charCode >= LOWERCASE_A_CODE && charCode <= LOWERCASE_F_CODE;
|
|
21
|
+
}
|
|
22
|
+
function isGuidString(key) {
|
|
23
|
+
if (key.length !== GUID_LENGTH) return false;
|
|
24
|
+
if (key.charCodeAt(GUID_SEPARATOR_ONE_INDEX) !== GUID_SEPARATOR_CODE || key.charCodeAt(GUID_SEPARATOR_TWO_INDEX) !== GUID_SEPARATOR_CODE || key.charCodeAt(GUID_SEPARATOR_THREE_INDEX) !== GUID_SEPARATOR_CODE || key.charCodeAt(GUID_SEPARATOR_FOUR_INDEX) !== GUID_SEPARATOR_CODE) return false;
|
|
25
|
+
for (let index = 0; index < key.length; index += 1) if (!(index === GUID_SEPARATOR_ONE_INDEX || index === GUID_SEPARATOR_TWO_INDEX || index === GUID_SEPARATOR_THREE_INDEX || index === GUID_SEPARATOR_FOUR_INDEX) && !isHexCode(key.charCodeAt(index))) return false;
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
function shouldConvertKey(key, options) {
|
|
29
|
+
if (isGuidString(key)) return false;
|
|
30
|
+
return options?.shouldConvert?.(key) !== false;
|
|
31
|
+
}
|
|
32
|
+
function keysToCamelCase(obj, options) {
|
|
33
|
+
if (Array.isArray(obj)) return obj.map((value) => keysToCamelCase(value, options));
|
|
8
34
|
if (obj === null || typeof obj !== "object") return obj;
|
|
9
35
|
const result = {};
|
|
10
36
|
for (const [key, value] of Object.entries(obj)) {
|
|
11
|
-
const camelKey = (0, __pixpilot_string.toCamelCase)(key);
|
|
12
|
-
result[camelKey] = keysToCamelCase(value);
|
|
37
|
+
const camelKey = shouldConvertKey(key, options) ? (0, __pixpilot_string.toCamelCase)(key) : key;
|
|
38
|
+
result[camelKey] = keysToCamelCase(value, options);
|
|
13
39
|
}
|
|
14
40
|
return result;
|
|
15
41
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
//#region src/keys-to-camel-case.d.ts
|
|
2
|
+
interface KeysToCamelCaseOptions {
|
|
3
|
+
shouldConvert?: (key: string) => boolean;
|
|
4
|
+
}
|
|
2
5
|
type CamelizeSegment<S extends string> = S extends '' ? '' : Capitalize<Lowercase<S>>;
|
|
3
6
|
/**
|
|
4
7
|
* Convert snake_case to camelCase at the type level.
|
|
@@ -12,6 +15,6 @@ type ToCamelCase<S extends string, IsFirst extends boolean = true> = S extends `
|
|
|
12
15
|
type Builtin = Date | RegExp | Map<unknown, unknown> | Set<unknown> | WeakMap<object, unknown> | WeakSet<object>;
|
|
13
16
|
type TupleToCamelCase<T extends readonly unknown[]> = { [I in keyof T]: KeysToCamelCase<T[I]> };
|
|
14
17
|
type KeysToCamelCase<T> = T extends Builtin ? T : T extends ((...args: unknown[]) => unknown) ? T : T extends readonly unknown[] ? number extends T['length'] ? KeysToCamelCase<T[number]>[] : TupleToCamelCase<T> : T extends object ? { [K in keyof T as K extends string ? ToCamelCase<K> : K]: KeysToCamelCase<T[K]> } : T;
|
|
15
|
-
declare function keysToCamelCase<T>(obj: T): KeysToCamelCase<T>;
|
|
18
|
+
declare function keysToCamelCase<T>(obj: T, options?: KeysToCamelCaseOptions): KeysToCamelCase<T>;
|
|
16
19
|
//#endregion
|
|
17
|
-
export { KeysToCamelCase, ToCamelCase, keysToCamelCase };
|
|
20
|
+
export { KeysToCamelCase, KeysToCamelCaseOptions, ToCamelCase, keysToCamelCase };
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
//#region src/keys-to-camel-case.d.ts
|
|
2
|
+
interface KeysToCamelCaseOptions {
|
|
3
|
+
shouldConvert?: (key: string) => boolean;
|
|
4
|
+
}
|
|
2
5
|
type CamelizeSegment<S extends string> = S extends '' ? '' : Capitalize<Lowercase<S>>;
|
|
3
6
|
/**
|
|
4
7
|
* Convert snake_case to camelCase at the type level.
|
|
@@ -12,6 +15,6 @@ type ToCamelCase<S extends string, IsFirst extends boolean = true> = S extends `
|
|
|
12
15
|
type Builtin = Date | RegExp | Map<unknown, unknown> | Set<unknown> | WeakMap<object, unknown> | WeakSet<object>;
|
|
13
16
|
type TupleToCamelCase<T extends readonly unknown[]> = { [I in keyof T]: KeysToCamelCase<T[I]> };
|
|
14
17
|
type KeysToCamelCase<T> = T extends Builtin ? T : T extends ((...args: unknown[]) => unknown) ? T : T extends readonly unknown[] ? number extends T['length'] ? KeysToCamelCase<T[number]>[] : TupleToCamelCase<T> : T extends object ? { [K in keyof T as K extends string ? ToCamelCase<K> : K]: KeysToCamelCase<T[K]> } : T;
|
|
15
|
-
declare function keysToCamelCase<T>(obj: T): KeysToCamelCase<T>;
|
|
18
|
+
declare function keysToCamelCase<T>(obj: T, options?: KeysToCamelCaseOptions): KeysToCamelCase<T>;
|
|
16
19
|
//#endregion
|
|
17
|
-
export { KeysToCamelCase, ToCamelCase, keysToCamelCase };
|
|
20
|
+
export { KeysToCamelCase, KeysToCamelCaseOptions, ToCamelCase, keysToCamelCase };
|
|
@@ -1,13 +1,39 @@
|
|
|
1
1
|
import { toCamelCase } from "@pixpilot/string";
|
|
2
2
|
|
|
3
3
|
//#region src/keys-to-camel-case.ts
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const FIRST_CHARACTER_INDEX = 0;
|
|
5
|
+
const GUID_LENGTH = 36;
|
|
6
|
+
const GUID_SEPARATOR_CODE = "-".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
7
|
+
const GUID_SEPARATOR_ONE_INDEX = 8;
|
|
8
|
+
const GUID_SEPARATOR_TWO_INDEX = 13;
|
|
9
|
+
const GUID_SEPARATOR_THREE_INDEX = 18;
|
|
10
|
+
const GUID_SEPARATOR_FOUR_INDEX = 23;
|
|
11
|
+
const ZERO_CODE = "0".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
12
|
+
const NINE_CODE = "9".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
13
|
+
const UPPERCASE_A_CODE = "A".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
14
|
+
const UPPERCASE_F_CODE = "F".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
15
|
+
const LOWERCASE_A_CODE = "a".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
16
|
+
const LOWERCASE_F_CODE = "f".charCodeAt(FIRST_CHARACTER_INDEX);
|
|
17
|
+
function isHexCode(charCode) {
|
|
18
|
+
return charCode >= ZERO_CODE && charCode <= NINE_CODE || charCode >= UPPERCASE_A_CODE && charCode <= UPPERCASE_F_CODE || charCode >= LOWERCASE_A_CODE && charCode <= LOWERCASE_F_CODE;
|
|
19
|
+
}
|
|
20
|
+
function isGuidString(key) {
|
|
21
|
+
if (key.length !== GUID_LENGTH) return false;
|
|
22
|
+
if (key.charCodeAt(GUID_SEPARATOR_ONE_INDEX) !== GUID_SEPARATOR_CODE || key.charCodeAt(GUID_SEPARATOR_TWO_INDEX) !== GUID_SEPARATOR_CODE || key.charCodeAt(GUID_SEPARATOR_THREE_INDEX) !== GUID_SEPARATOR_CODE || key.charCodeAt(GUID_SEPARATOR_FOUR_INDEX) !== GUID_SEPARATOR_CODE) return false;
|
|
23
|
+
for (let index = 0; index < key.length; index += 1) if (!(index === GUID_SEPARATOR_ONE_INDEX || index === GUID_SEPARATOR_TWO_INDEX || index === GUID_SEPARATOR_THREE_INDEX || index === GUID_SEPARATOR_FOUR_INDEX) && !isHexCode(key.charCodeAt(index))) return false;
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
function shouldConvertKey(key, options) {
|
|
27
|
+
if (isGuidString(key)) return false;
|
|
28
|
+
return options?.shouldConvert?.(key) !== false;
|
|
29
|
+
}
|
|
30
|
+
function keysToCamelCase(obj, options) {
|
|
31
|
+
if (Array.isArray(obj)) return obj.map((value) => keysToCamelCase(value, options));
|
|
6
32
|
if (obj === null || typeof obj !== "object") return obj;
|
|
7
33
|
const result = {};
|
|
8
34
|
for (const [key, value] of Object.entries(obj)) {
|
|
9
|
-
const camelKey = toCamelCase(key);
|
|
10
|
-
result[camelKey] = keysToCamelCase(value);
|
|
35
|
+
const camelKey = shouldConvertKey(key, options) ? toCamelCase(key) : key;
|
|
36
|
+
result[camelKey] = keysToCamelCase(value, options);
|
|
11
37
|
}
|
|
12
38
|
return result;
|
|
13
39
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixpilot/object",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.0",
|
|
5
5
|
"description": "A collection of utility functions for object manipulation and transformation.",
|
|
6
6
|
"author": "Pixpilot <m.doaie@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"eslint": "^9.37.0",
|
|
36
36
|
"tsdown": "^0.15.8",
|
|
37
37
|
"typescript": "^5.9.3",
|
|
38
|
+
"@internal/eslint-config": "0.3.0",
|
|
38
39
|
"@internal/prettier-config": "0.0.1",
|
|
39
40
|
"@internal/tsconfig": "0.1.0",
|
|
40
|
-
"@internal/
|
|
41
|
-
"@internal/tsdown-config": "0.1.0"
|
|
42
|
-
"@internal/vitest-config": "0.1.0"
|
|
41
|
+
"@internal/vitest-config": "0.1.0",
|
|
42
|
+
"@internal/tsdown-config": "0.1.0"
|
|
43
43
|
},
|
|
44
44
|
"prettier": "@internal/prettier-config",
|
|
45
45
|
"scripts": {
|