pathtrace

Simplifies working with nested objects and arrays by providing easy methods to retrieve, set, and check values at any path.

MIT License

Downloads
3.5K
Stars
1

pathtrace 🔍

Pathtrace is a library for managing nested objects and arrays. It offers straightforward methods for retrieving (getPathValue) and setting (setPathValue) values at any path. Additionally, getPathInfo provides detailed path information, and the expandPath helper allows for querying and expanding paths with wildcards and globstars, making it ideal for handling complex data structures efficiently.

Table of Contents

Installation

npm install pathtrace --save

Usage

The following examples demonstrate how to use the library.

getPathValue

This method retrieves the value of a property at a given path inside an object.

const obj = {
    user: {
        name: 'Alice',
        roles: ['admin', 'editor'],
        contact: {
            email: '[email protected]',
            phone: '123-456-7890',
        },
    },
    settings: [
        { theme: 'dark' },
        { notifications: true },
        [{ privacy: 'high' }]
    ]
};

Example 1: Retrieving a simple property value

import { getPathValue } from 'pathtrace';

var value = getPathValue(obj, 'user.name');
console.log(value); // 'Alice'

Example 2: Retrieving a nested property value

import { getPathValue } from 'pathtrace';

var value = getPathValue(obj, 'user.contact.email');
console.log(value); // '[email protected]'

Example 3: Retrieving an array element by index

import { getPathValue } from 'pathtrace';

var value = getPathValue(obj, 'user.roles[1]');
console.log(value); // 'editor'

Example 4: Retrieving a nested property within an array

import { getPathValue } from 'pathtrace';

var value = getPathValue(obj, 'settings[1].notifications');
console.log(value); // true

Example 5: Retrieving a value from a multi-dimensional array

import { getPathValue } from 'pathtrace';

var value = getPathValue(obj, 'settings[2][0].privacy');
console.log(value); // 'high'

Example 6: Handling undefined objects and properties

import { getPathValue } from 'pathtrace';

var value = getPathValue(undefined, 'user.name');
console.log(value); // undefined

var value = getPathValue(obj, 'user.address');
console.log(value); // undefined

var value = getPathValue('hello', 'length');
console.log(value); // 5

setPathValue

This method sets the value of a property at a given path inside an object and returns the object in which the property has been set.

var obj = {
    user: {
        name: 'Alice',
        roles: ['admin', 'editor'],
        contact: {
            email: '[email protected]',
            phone: '123-456-7890',
        },
    },
    settings: [
        { theme: 'dark' },
        { notifications: true },
        [{ privacy: 'high' }]
    ]
};

Example 1: Setting a simple property value

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'user.name', 'Bob');
console.log(obj.user.name); // 'Bob'

Example 2: Setting a nested property value

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'user.contact.email', '[email protected]');
console.log(obj.user.contact.email); // '[email protected]'

Example 3: Setting a nested array value

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'user.roles[1]', 'viewer');
console.log(obj.user.roles[1]); // 'viewer'

Example 4: Setting a value in an array

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'settings[2][0].privacy', 'low');
console.log(obj.settings[2][0].privacy); // 'low'

Example 5: Adding a new property to an object

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'user.contact.address', '123 Main St');
console.log(obj.user.contact.address); // '123 Main St'

Example 6: Setting a value in an object within an array

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'settings[1].notifications', false);
console.log(obj.settings[1].notifications); // false

Example 7: Creating a new array and setting values

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'user.history[0]', 'logged in');
setPathValue(obj, 'user.history[2]', 'logged out');
console.log(obj.user.history[0]); // 'logged in'
console.log(obj.user.history[1]); // undefined
console.log(obj.user.history[2]); // 'logged out'

Example 8: Setting a value in a multi-dimensional array

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'settings[2][1]', { secure: true });
console.log(obj.settings[2][1].secure); // true

Example 9: Setting a value in an object inside an array

import { setPathValue } from 'pathtrace';

setPathValue(obj, 'settings[2][0].description', 'private settings');
console.log(obj.settings[2][0].description); // 'private settings'

Example 10: Returning the modified object

import { setPathValue } from 'pathtrace';

var modifiedObj = setPathValue(obj, 'user.contact.phone', '987-654-3210');
console.log(modifiedObj === obj); // true

expandPath

The expandPath function takes an object and a string representing a path, potentially containing wildcards (*) and globstars (**), and returns an array of all possible matching paths within the object.

Example: Wildcard (*) - Select all shallow paths of an array

import { expandPath } from 'pathtrace';

const obj = {
    foo: ['bar', 'baz'],
};
const paths = expandPath(obj, 'foo.*');
console.log(paths); // ['foo[0]', 'foo[1]']

Example: Wildcard (*) - Select matching paths under a wildcard branch

import { expandPath } from 'pathtrace';

const obj = { foo: { bar: { a: true }, baz: { a: false, b: 1 } } };
const paths = expandPath(obj, 'foo.*.a');
console.log(paths); // ['foo.bar.a', 'foo.baz.a']

Example: Globstar (**) - Select all leaves that match a leaf globstar

import { expandPath } from 'pathtrace';

const obj = { foo: { a: { b: { c: 1 } }, d: { e: 2 } } };
const paths = expandPath(obj, 'foo.**');
console.log(paths); // ['foo.a.b.c', 'foo.d.e']

Example: Globstar (**) - Select deeply nested matching paths under a globstar branch

import { expandPath } from 'pathtrace';

const obj = { foo: { a: { b: { bar: 1 } }, c: { bar: 2 } } };
const paths = expandPath(obj, 'foo.**.bar');
console.log(paths); // ['foo.a.b.bar', 'foo.c.bar']

getPathInfo

This method returns an object with information indicating the value of the parent of that path, the name of the property being retrieved, and its value.

const obj = {
    user: {
        name: 'Alice',
        roles: ['admin', 'editor'],
        contact: {
            email: '[email protected]',
            phone: '123-456-7890',
        },
    },
    'user.roles': {
        '[1]': 'editor',
    },
};

Example 1: Handling a nested property

import { getPathInfo } from 'pathtrace';

const info = getPathInfo(obj, 'user.contact.email');

if (info.parent) {
    console.log(info.parent.name); // 'contact'
    console.log(info.parent.value); 
    // { email: '[email protected]', phone: '123-456-7890' }
    console.log(info.parent.exists); // true
}
console.log(info.value); // '[email protected]'
console.log(info.exists); // true
console.log(info.name); // 'email'

Example 2: Handling an array index

import { getPathInfo } from 'pathtrace';

const info = getPathInfo(obj, 'user.roles[1]');

if (info.parent) {
    console.log(info.parent.name); // 'roles'
    console.log(info.parent.value); // ['admin', 'editor']
    console.log(info.parent.exists); // true
}
console.log(info.value); // 'editor'
console.log(info.name); // '1'
console.log(info.exists); // true

Example 3: Handling a non-existent property

import { getPathInfo } from 'pathtrace';

const info = getPathInfo(obj, 'user.contact.address');

if (info.parent) {
    console.log(info.parent.name); // 'contact'
    console.log(info.parent.value); 
    // { email: '[email protected]', phone: '123-456-7890' }
    console.log(info.parent.exists); // true
}
console.log(info.value); // undefined
console.log(info.name); // 'address'
console.log(info.exists); // false

Example 4: Handling an out-of-bounds array index

import { getPathInfo } from 'pathtrace';

const info = getPathInfo(obj, 'user.roles[5]');

if (info.parent) {
    console.log(info.parent.name); // 'roles'
    console.log(info.parent.value); // ['admin', 'editor']
    console.log(info.parent.exists); // true
}
console.log(info.value); // undefined
console.log(info.name); // '5'
console.log(info.exists); // false

Example 5: Handling backslash-escaping for . and []

import { getPathInfo } from 'pathtrace';

const info = getPathInfo(obj, 'user\\.roles.\\[1\\]');

if (info.parent) {
    console.log(info.parent.name); // '[1]'
    console.log(info.parent.value); // 'editor'
    console.log(info.exists); // true
}
console.log(info.value); // 'editor'
console.log(info.name); // '1'
console.log(info.exists); // true

removePath

This method removes a property by a given path inside an object.

import { removePath } from 'pathtrace';

const obj = {
    hello: 'universe',
    foo: 'bar',
};

removePath(obj, 'foo');

console.log(obj);
// { hello: 'universe' }

License

Made with 💚

Package Rankings
Top 31.73% on Npmjs.org
Badges
Extracted from project README
npm version codecov main Known Vulnerabilities Conventional Commits