or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-operations.mdasync-promise-utilities.mddata-utilities.mdfunction-utilities.mdindex.mdobject-operations.mdpath-operations.mdperformance-benchmarking.mdstring-utilities.mdvalidation-assertions.md
tile.json

path-operations.mddocs/

Path Operations

Object property traversal and template replacement utilities using dot notation and bracket syntax for nested data access with support for arrays, functions, and iterables.

Capabilities

Reach

Converts an object key chain string or array to reference, providing safe traversal of nested object properties.

/**
 * Convert an object key chain string to reference
 * @param obj - The object from which to look up the value
 * @param chain - The string path or array of keys. Negative numbers work like negative array indices
 * @param options - Optional settings for traversal behavior
 * @returns The value referenced by the chain if found, otherwise undefined
 */
function reach(obj: object | null, chain: string | (string | number)[] | false | null | undefined, options?: reach.Options): any;

namespace reach {
  interface Options {
    /** String to split chain path on. Defaults to '.' */
    readonly separator?: string;
    /** Value to return if the path or value is not present. No default value */
    readonly default?: any;
    /** If true, will throw an error on missing member in the chain. Defaults to false */
    readonly strict?: boolean;
    /** If true, allows traversing functions for properties. false will throw error if function is part of chain. Defaults to true */
    readonly functions?: boolean;
    /** If true, allows traversing Set and Map objects for properties. Defaults to false */
    readonly iterables?: boolean;
  }
}

Usage Examples:

import { reach } from "@hapi/hoek";

// Basic dot notation traversal
const obj = { a: { b: { c: 1 } } };
const value = reach(obj, 'a.b.c'); // 1

// Array-style key specification
const arrayKeys = reach(obj, ['a', 'b', 'c']); // 1

// Array index access including negative indices
const arrayObj = { a: { b: [2, 3, 6] } };
const lastItem = reach(arrayObj, ['a', 'b', -1]); // 6
const firstItem = reach(arrayObj, 'a.b.0'); // 2

// Default values for missing paths
const missing = reach(obj, 'a.x.y', { default: 'not found' }); // 'not found'

// Custom separator
const colonObj = { 'user:profile:name': 'Alice' };
const customSep = reach(colonObj, 'user:profile:name', { separator: ':' }); // Won't work as expected
// Better approach:
const nestedObj = { user: { profile: { name: 'Alice' } } };
const name = reach(nestedObj, 'user:profile:name', { separator: ':' }); // 'Alice'

// Strict mode throws on missing properties
try {
  reach(obj, 'a.missing.path', { strict: true }); // Throws error
} catch (error) {
  console.log('Path not found');
}

// Function traversal
const funcObj = {
  getValue: function() { return { nested: 'value' }; }
};
const funcResult = reach(funcObj, 'getValue.nested', { functions: true }); // 'value'

// Null/undefined chain returns the object itself
const self = reach(obj, null); // obj
const selfUndefined = reach(obj, undefined); // obj
const selfFalse = reach(obj, false); // obj

Reach Template

Replaces string parameters (using format "{path.to.key}") with their corresponding object key values using the reach functionality.

/**
 * Replace string parameters (using format "{path.to.key}") with their corresponding object key values using Hoek.reach()
 * @param obj - The object from which to look up the value
 * @param template - The string containing {} enclosed key paths to be replaced
 * @param options - Optional reach.Options for path traversal behavior
 * @returns The template string with {} enclosed keys replaced with looked-up values
 */
function reachTemplate(obj: object | null, template: string, options?: reach.Options): string;

Usage Examples:

import { reachTemplate } from "@hapi/hoek";

// Basic template replacement
const data = { 
  user: { name: 'Alice', id: 123 },
  action: 'login',
  timestamp: '2023-01-01'
};

const template = 'User {user.name} performed {action} at {timestamp}';
const result = reachTemplate(data, template);
// Result: 'User Alice performed login at 2023-01-01'

// Mathematical expressions in templates
const mathData = { a: { b: { c: 1 } } };
const mathTemplate = '1+{a.b.c}=2';
const mathResult = reachTemplate(mathData, mathTemplate);
// Result: '1+1=2'

// Multiple occurrences of same path
const repeatTemplate = '{user.name} says hello to {user.name}';
const repeatResult = reachTemplate(data, repeatTemplate);
// Result: 'Alice says hello to Alice'

// Array access in templates
const arrayData = { 
  users: ['Alice', 'Bob', 'Charlie'],
  scores: [100, 85, 92]
};
const arrayTemplate = 'Winner: {users.0} with score {scores.0}';
const arrayResult = reachTemplate(arrayData, arrayTemplate);
// Result: 'Winner: Alice with score 100'

// Nested object templates
const nestedData = {
  config: {
    server: { host: 'localhost', port: 8080 },
    database: { name: 'myapp' }
  }
};
const nestedTemplate = 'Server running at {config.server.host}:{config.server.port} using {config.database.name}';
const nestedResult = reachTemplate(nestedData, nestedTemplate);
// Result: 'Server running at localhost:8080 using myapp'

// Missing values are replaced with empty string
const missingTemplate = 'User {user.name} has {user.missing} points';
const missingResult = reachTemplate(data, missingTemplate);
// Result: 'User Alice has  points'

// Custom separator with reach options
const customData = { 'level1': { 'level2': { 'value': 'found' } } };
const customTemplate = 'Value: {level1:level2:value}';
const customResult = reachTemplate(customData, customTemplate, { separator: ':' });
// Result: 'Value: found'

Important Notes:

  • Template replacement uses the same path resolution as reach(), supporting all its options
  • Missing or undefined paths in templates are replaced with empty strings in the output
  • The {} syntax is specifically for path replacement - literal braces need to be escaped if needed
  • All reach.Options are supported for customizing path traversal behavior
  • Template replacement is performed sequentially for each {path} found in the string