Initial commit

This commit is contained in:
2024-12-03 22:52:21 +02:00
parent 986458dd4b
commit aba68a3c0a
43 changed files with 14905 additions and 1 deletions

38
src/object/compare.ts Normal file
View File

@@ -0,0 +1,38 @@
/**
* Performs object comparison with optional deep comparison
* @param obj First object to compare
* @param objToCompare Second object to compare
* @param deep Enable deep comparison for nested objects/arrays
*/
export function objectCompare<T extends Record<string, unknown>>(
obj: T,
objToCompare: T,
deep = false
): boolean {
if (!obj || !objToCompare) return false;
return Object.keys(obj).length === Object.keys(objToCompare).length &&
Object.keys(obj).every((key) => {
if (!Object.prototype.hasOwnProperty.call(objToCompare, key)) return false;
const val1 = obj[key];
const val2 = objToCompare[key];
if (!deep) return val1 === val2;
if (Array.isArray(val1) && Array.isArray(val2)) {
return val1.length === val2.length &&
val1.every((item, i) =>
typeof item === 'object' && item !== null
? objectCompare(item as Record<string, unknown>, val2[i] as Record<string, unknown>, true)
: item === val2[i]
);
}
if (typeof val1 === 'object' && typeof val2 === 'object' && val1 !== null && val2 !== null) {
return objectCompare(val1 as Record<string, unknown>, val2 as Record<string, unknown>, true);
}
return val1 === val2;
});
}

3
src/object/index.ts Normal file
View File

@@ -0,0 +1,3 @@
export {getNestedValue,setNestedValue} from './nested'
export {objectCompare} from './compare'
export {createSelectOptions} from './util'

46
src/object/nested.ts Normal file
View File

@@ -0,0 +1,46 @@
/**
* Gets a nested value from an object using a path string
* @param path - Dot notation path (e.g. 'user.contacts[0].email')
* @param obj - Source object to extract value from
* @returns Value at path or undefined if path invalid
*/
export function getNestedValue(path: string, obj: Record<string, any>): any {
return path
.replace(/\[(\w+)\]/g, ".$1") // Convert brackets to dot notation
.split(".") // Split path into parts
.reduce((prev, curr) => prev?.[curr], obj); // Traverse object
}
/**
* Sets a nested value in an object using a path string
* @param path - Dot notation path (e.g. 'user.contacts[0].email')
* @param value - Value to set at path
* @param obj - Target object to modify
* @returns Modified object
*/
/**
* Sets a nested value, creating objects and arrays if needed
*/
export function setNestedValue(path: string, value: any, obj: Record<string, any>): Record<string, any> {
const parts = path.replace(/\[(\w+)\]/g, ".$1").split(".");
const lastKey = parts.pop()!;
const target = parts.reduce((prev, curr) => {
// Handle array indices
if (/^\d+$/.test(curr)) {
if (!Array.isArray(prev[curr])) {
prev[curr] = [];
}
}
// Create missing objects
else if (!prev[curr]) {
prev[curr] = {};
}
return prev[curr];
}, obj);
target[lastKey] = value;
return obj;
}

49
src/object/util.ts Normal file
View File

@@ -0,0 +1,49 @@
/**
* Converts an object or array into an array of key-value pairs with customizable property names.
* Commonly used for transforming data into a format suitable for select/dropdown components.
*
* @param obj - The input object or array to be transformed
* @param options - Configuration options for the transformation
* @param options.labelKey - The key name to use for the label property (default: 'label')
* @param options.valueKey - The key name to use for the value property (default: 'value')
* @returns An array of objects with the specified label and value properties, or an empty array if input is invalid
*
* @example
* // Basic usage
* createSelectOptions({ key1: "Label 1", key2: "Label 2" })
* // Returns: [{ label: "Label 1", value: "key1" }, { label: "Label 2", value: "key2" }]
*
* // Custom key names
* createSelectOptions(
* { key1: "Label 1", key2: "Label 2" },
* { labelKey: 'text', valueKey: 'id' }
* )
* // Returns: [{ text: "Label 1", id: "key1" }, { text: "Label 2", id: "key2" }]
*/
export function createSelectOptions<T = string>(
obj: Record<string, T> | T[] | null | undefined,
options: {
labelKey?: string;
valueKey?: string;
} = {}
): Array<Record<string, T | string>> {
const {
labelKey = 'label',
valueKey = 'value'
} = options;
// Return empty array for null or undefined input
if (!obj) return [];
// Return the original array if input is already an array
if (Array.isArray(obj)) return obj as Array<Record<string, T | string>>;
// Return empty array for non-object inputs (like numbers or strings)
if (typeof obj !== 'object') return [];
// Transform object into array of key-value pairs with custom property names
return Object.keys(obj).map((key) => ({
[labelKey]: obj[key],
[valueKey]: key
}));
}