CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-hapi--hoek

General purpose node utilities providing object manipulation, array operations, string utilities, data validation, async utilities, and path operations for the hapi ecosystem.

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

data-utilities.mddocs/

Data Utilities

Safe data serialization utilities with error handling for JSON conversion operations, providing robust string representation of JavaScript values.

Capabilities

Stringify

Converts a JavaScript value to a JSON string with protection against thrown errors, providing safe serialization for any value including circular references.

/**
 * Converts a JavaScript value to a JavaScript Object Notation (JSON) string with protection against thrown errors
 * @param value - A JavaScript value, usually an object or array, to be converted
 * @param replacer - The JSON.stringify() replacer argument
 * @param space - Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read
 * @returns The JSON string. If the operation fails, an error string value is returned (no exception thrown)
 */
function stringify(value: any, replacer?: any, space?: string | number): string;

Usage Examples:

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

// Basic object stringification
const simpleObj = { name: 'Alice', age: 30, active: true };
const jsonString = stringify(simpleObj);
// Result: '{"name":"Alice","age":30,"active":true}'

// Pretty printing with indentation
const prettyJson = stringify(simpleObj, null, 2);
/* Result:
{
  "name": "Alice",
  "age": 30,
  "active": true
}
*/

// Safe circular reference handling
const circularObj: any = { name: 'test' };
circularObj.self = circularObj; // Create circular reference

const safeCircular = stringify(circularObj);
// Result: '[Cannot display object: Converting circular structure to JSON]'
// No exception thrown, unlike JSON.stringify()

// Complex nested objects
const complexObj = {
  users: [
    { id: 1, name: 'Alice', metadata: { active: true, roles: ['admin', 'user'] } },
    { id: 2, name: 'Bob', metadata: { active: false, roles: ['user'] } }
  ],
  config: {
    timeout: 5000,
    retries: 3,
    endpoints: ['api.example.com', 'backup.example.com']
  }
};

const complexJson = stringify(complexObj, null, 2);
// Safely converts entire complex structure

// Custom replacer function
const objWithSensitiveData = {
  username: 'alice',
  password: 'secret123',
  email: 'alice@example.com',
  profile: { age: 30, city: 'New York' }
};

const safeReplacer = (key: string, value: any) => {
  if (key === 'password') return '[REDACTED]';
  return value;
};

const redactedJson = stringify(objWithSensitiveData, safeReplacer, 2);
// Result includes password as '[REDACTED]'

// Array replacer for key filtering
const arrayReplacer = ['username', 'email', 'profile'];
const filteredJson = stringify(objWithSensitiveData, arrayReplacer, 2);
// Only includes specified keys

// Error object stringification
const error = new Error('Something went wrong');
error.code = 'ERR_CUSTOM';
error.details = { step: 'validation', field: 'email' };

const errorJson = stringify(error);
// Safely converts error object (JSON.stringify would lose most properties)

// Date and special value handling
const specialValues = {
  now: new Date(),
  undefined: undefined,
  null: null,
  infinity: Infinity,
  nan: NaN,
  bigint: 123n
};

const specialJson = stringify(specialValues, null, 2);
// Handles all special JavaScript values safely

// Function and symbol handling
const objWithFunctions = {
  data: 'value',
  method: function() { return 'result'; },
  symbol: Symbol('test'),
  arrow: () => 'arrow result'
};

const funcJson = stringify(objWithFunctions);
// Functions and symbols are handled according to JSON.stringify rules

// Safe logging utility
function safeLog(label: string, value: any) {
  console.log(`${label}:`, stringify(value, null, 2));
}

// Usage in error handling
try {
  riskyOperation();
} catch (error) {
  console.error('Operation failed:', stringify(error));
  // Safe even if error object has circular references or other issues
}

// API response debugging
async function debugAPIResponse(url: string) {
  try {
    const response = await fetch(url);
    const data = await response.json();
    
    console.log('Response data:', stringify(data, null, 2));
    return data;
  } catch (error) {
    console.error('API Error:', stringify({
      url,
      error: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString()
    }, null, 2));
    throw error;
  }
}

// Configuration serialization
function serializeConfig(config: any): string {
  return stringify(config, (key, value) => {
    // Redact sensitive configuration values
    if (key.toLowerCase().includes('password') || 
        key.toLowerCase().includes('secret') ||
        key.toLowerCase().includes('token')) {
      return '[REDACTED]';
    }
    return value;
  }, 2);
}

// Safe state serialization for debugging
class StatefulComponent {
  private state: any;
  
  getStateSnapshot(): string {
    return stringify(this.state, null, 2);
  }
  
  debugState(): void {
    console.log('Current state:', this.getStateSnapshot());
  }
}

// Large object handling
function handleLargeObject(largeObj: any) {
  try {
    // Try normal JSON.stringify first for performance
    return JSON.stringify(largeObj);
  } catch (error) {
    // Fall back to safe stringify
    console.warn('Large object has issues, using safe stringify');
    return stringify(largeObj);
  }
}

// Custom space formatting
const customSpaceObj = { a: 1, b: { c: 2, d: 3 } };

// Using string space
const tabFormatted = stringify(customSpaceObj, null, '\t');

// Using number space
const fourSpaceFormatted = stringify(customSpaceObj, null, 4);

// No formatting
const minified = stringify(customSpaceObj);

// Testing and development utilities
function createTestSnapshot(testData: any): string {
  return stringify(testData, (key, value) => {
    // Normalize timestamps for consistent testing
    if (key.includes('timestamp') || key.includes('time')) {
      return '[TIMESTAMP]';
    }
    // Normalize IDs
    if (key === 'id' && typeof value === 'string') {
      return '[ID]';
    }
    return value;
  }, 2);
}

Important Notes:

  • stringify never throws exceptions, unlike JSON.stringify() which can throw on circular references
  • When JSON conversion fails, it returns a descriptive error string instead of throwing
  • Supports all the same parameters as JSON.stringify(): value, replacer, and space
  • Perfect for logging, debugging, and error handling where safety is more important than performance
  • Handles circular references, functions, symbols, and other problematic values gracefully
  • The error message format is: '[Cannot display object: <error description>]'
  • More robust than JSON.stringify() for untrusted or complex data structures
  • Ideal for development tools, debugging utilities, and error reporting systems

docs

array-operations.md

async-promise-utilities.md

data-utilities.md

function-utilities.md

index.md

object-operations.md

path-operations.md

performance-benchmarking.md

string-utilities.md

validation-assertions.md

tile.json