CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jsonpath

Query JavaScript objects with JSONPath expressions using a robust and safe JSONPath engine for Node.js.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

manipulation.mddocs/

Value Manipulation

Functions for getting, setting, and transforming values at specific JSONPath locations. Includes support for creating intermediate objects (vivification) and applying transformations to multiple matching elements in place.

Capabilities

Value Function

Get or set the value of the first element matching a JSONPath expression. When setting values, it creates intermediate objects as needed.

/**
 * Get or set value of first matching element
 * @param {Object} obj - Target object (must be an object)
 * @param {string|Array} pathExpression - JSONPath expression string or normalized path array
 * @param {*} [newValue] - New value to set (optional, creates intermediate objects/arrays as needed)
 * @returns {*} Current value (if getting) or new value (if setting)
 */
function value(obj, pathExpression, newValue);

Usage Examples:

const jp = require('jsonpath');

const data = { 
  store: { 
    book: [
      { author: "Nigel Rees", price: 8.95 },
      { author: "Evelyn Waugh", price: 12.99 }
    ]
  } 
};

// Get first matching value
const firstAuthor = jp.value(data, '$..author');
// Result: "Nigel Rees"

const firstPrice = jp.value(data, '$..price');  
// Result: 8.95

// Set existing value
jp.value(data, '$..price', 9.99);
console.log(data.store.book[0].price); // 9.99

// Create new properties (vivification)
const emptyObj = {};
jp.value(emptyObj, '$.store.name', 'My Bookstore');
console.log(emptyObj); // { store: { name: 'My Bookstore' } }

// Create array elements
jp.value(emptyObj, '$.items[0]', 'first item');
jp.value(emptyObj, '$.items[1]', 'second item');
console.log(emptyObj.items); // ['first item', 'second item']

// Set values using complex expressions
jp.value(data, '$..book[?(@.author=="Nigel Rees")].price', 10.50);

Parent Function

Get the parent object of the first element matching a JSONPath expression.

/**
 * Get parent of first matching element
 * @param {Object} obj - Target object (must be an object)
 * @param {string} pathExpression - JSONPath expression string
 * @returns {*} Parent object of first match
 */
function parent(obj, pathExpression);

Usage Examples:

const jp = require('jsonpath');

const data = { 
  store: { 
    book: [
      { author: "Nigel Rees", title: "Sayings", price: 8.95 },
      { author: "Evelyn Waugh", title: "Sword", price: 12.99 }
    ]
  } 
};

// Get parent of first author
const parentOfAuthor = jp.parent(data, '$..author');
console.log(parentOfAuthor); 
// Result: { author: "Nigel Rees", title: "Sayings", price: 8.95 }

// Get parent of a specific book
const parentOfBook = jp.parent(data, '$.store.book[0]');
console.log(parentOfBook);
// Result: [{ author: "Nigel Rees", ... }, { author: "Evelyn Waugh", ... }]

// Get parent of specific property
const parentOfPrice = jp.parent(data, '$.store.book[1].price');
console.log(parentOfPrice);
// Result: { author: "Evelyn Waugh", title: "Sword", price: 12.99 }

Apply Function

Apply a transformation function to all elements matching a JSONPath expression, modifying them in place. Returns the modified nodes.

/**
 * Apply function to all matching elements, modifying them in place
 * @param {Object} obj - Target object (must be an object)
 * @param {string} pathExpression - JSONPath expression string
 * @param {Function} fn - Transformation function: (value) => newValue
 * @returns {Array<Object>} Array of modified node objects with {path: Array, value: any}
 */
function apply(obj, pathExpression, fn);

Usage Examples:

const jp = require('jsonpath');

const data = { 
  store: { 
    book: [
      { author: "nigel rees", price: 8.95 },
      { author: "evelyn waugh", price: 12.99 }
    ]
  } 
};

// Transform all author names to uppercase
const modifiedNodes = jp.apply(data, '$..author', function(value) {
  return value.toUpperCase();
});

console.log(modifiedNodes);
// Result: [
//   { path: ['$', 'store', 'book', 0, 'author'], value: 'NIGEL REES' },
//   { path: ['$', 'store', 'book', 1, 'author'], value: 'EVELYN WAUGH' }
// ]

console.log(data.store.book[0].author); // "NIGEL REES" (modified in place)

// Apply price discount to all books
jp.apply(data, '$..price', function(price) {
  return price * 0.9; // 10% discount
});

// Transform arrays (e.g., reverse order)
const arrayData = { numbers: [1, 2, 3], letters: ['a', 'b', 'c'] };
jp.apply(arrayData, '$..*[?(@.length > 1)]', function(array) {
  return array.reverse();
});
console.log(arrayData.numbers); // [3, 2, 1]

// Complex transformations using context
jp.apply(data, '$..book[*]', function(book) {
  return {
    ...book,
    slug: book.author.toLowerCase().replace(/\s+/g, '-'),
    discountedPrice: book.price * 0.8
  };
});

Advanced Features

Vivification (Auto-creation)

The value function automatically creates intermediate objects and arrays when setting values on non-existent paths:

const jp = require('jsonpath');

const obj = {};

// Creates nested object structure
jp.value(obj, '$.user.profile.name', 'John');
console.log(obj); 
// Result: { user: { profile: { name: 'John' } } }

// Creates array with specific index
jp.value(obj, '$.user.hobbies[0]', 'reading');
jp.value(obj, '$.user.hobbies[2]', 'hiking');
console.log(obj.user.hobbies); 
// Result: ['reading', undefined, 'hiking']

// Mixed structures
jp.value(obj, '$.data.items[0].tags[1]', 'important');
console.log(obj.data.items);
// Result: [{ tags: [undefined, 'important'] }]

Transformation Ordering

The apply function processes matches from bottom-up (deepest paths first) to handle structural changes safely:

const jp = require('jsonpath');

const data = { a: { b: [1, { c: [2, 3] }] } };

// This works safely even though it modifies structure
jp.apply(data, '$..*[?(@.length > 1)]', function(array) {
  return array.reverse();
});

console.log(data); 
// Result: { a: { b: [{ c: [3, 2] }, 1] } }

Error Handling

All manipulation functions validate their inputs:

  • Throws AssertionError if obj is not an object
  • Throws AssertionError if pathExpression is not valid
  • Throws AssertionError if fn is not a function (for apply)
  • parent throws error if no matches found
  • value returns undefined if getting non-existent path
  • apply returns empty array if no matches found

docs

index.md

manipulation.md

path-processing.md

querying.md

tile.json