From aa929fd0dcf3eb8f18dae4f2935a3ab9734eb50a Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Sun, 12 Jan 2025 09:57:29 +0100 Subject: [PATCH] refactor: create utility for nested templates --- packages/utils/index.ts | 4 +++- .../{array-utils => common}/arrayUtils.test.ts | 0 .../src/{array-utils => common}/arrayUtils.ts | 0 packages/utils/src/common/objectUtils.ts | 18 ++++++++++++++++++ packages/utils/src/common/objectUtilts.test.ts | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) rename packages/utils/src/{array-utils => common}/arrayUtils.test.ts (100%) rename packages/utils/src/{array-utils => common}/arrayUtils.ts (100%) create mode 100644 packages/utils/src/common/objectUtils.ts create mode 100644 packages/utils/src/common/objectUtilts.test.ts diff --git a/packages/utils/index.ts b/packages/utils/index.ts index 138b3c70a7..6a7e29e945 100644 --- a/packages/utils/index.ts +++ b/packages/utils/index.ts @@ -63,7 +63,9 @@ export { customFieldLabelToKey } from './src/customField-utils/customFieldLabelT export { deepmerge } from './src/externals/deepmerge.js'; // array utils -export { deleteAtIndex, insertAtIndex, reorderArray } from './src/array-utils/arrayUtils.js'; +export { deleteAtIndex, insertAtIndex, reorderArray } from './src/common/arrayUtils.js'; +// object utils +export { getPropertyFromPath } from './src/common/objectUtils.js'; // generic utilities export { getErrorMessage } from './src/generic/generic.js'; diff --git a/packages/utils/src/array-utils/arrayUtils.test.ts b/packages/utils/src/common/arrayUtils.test.ts similarity index 100% rename from packages/utils/src/array-utils/arrayUtils.test.ts rename to packages/utils/src/common/arrayUtils.test.ts diff --git a/packages/utils/src/array-utils/arrayUtils.ts b/packages/utils/src/common/arrayUtils.ts similarity index 100% rename from packages/utils/src/array-utils/arrayUtils.ts rename to packages/utils/src/common/arrayUtils.ts diff --git a/packages/utils/src/common/objectUtils.ts b/packages/utils/src/common/objectUtils.ts new file mode 100644 index 0000000000..b481c90157 --- /dev/null +++ b/packages/utils/src/common/objectUtils.ts @@ -0,0 +1,18 @@ +/** + * Extracts a value from a nested object using a dot-separated path + */ +export function getPropertyFromPath(path: string, obj: T): any | undefined { + const keys = path.split('.'); + let result: any = obj; + + // iterate through variable parts, and look for the property in the given object + for (const key of keys) { + if (result && typeof result === 'object' && key in result) { + result = result[key]; + } else { + return undefined; + } + } + + return result; +} diff --git a/packages/utils/src/common/objectUtilts.test.ts b/packages/utils/src/common/objectUtilts.test.ts new file mode 100644 index 0000000000..c4a8803615 --- /dev/null +++ b/packages/utils/src/common/objectUtilts.test.ts @@ -0,0 +1,17 @@ +import { getPropertyFromPath } from './objectUtils'; + +describe('getNestedFromTemplate', () => { + it('should return the value of a nested property', () => { + expect(getPropertyFromPath('a', { a: 1 })).toBe(1); + expect(getPropertyFromPath('a.b', { a: { b: 1 } })).toBe(1); + expect(getPropertyFromPath('a.b.c', { a: { b: { c: 1 } } })).toBe(1); + }); + + it('should guard against values that do not exist', () => { + expect(getPropertyFromPath('c', {})).toBe(undefined); + expect(getPropertyFromPath('c', { a: 1 })).toBe(undefined); + expect(getPropertyFromPath('a.c', { a: { b: 1 } })).toBeUndefined(); + expect(getPropertyFromPath('c.a', { a: { b: 1 } })).toBeUndefined(); + expect(getPropertyFromPath('a.b.b', { a: { b: { c: 1 } } })).toBeUndefined(); + }); +});