General purpose node utilities providing object manipulation, array operations, string utilities, data validation, async utilities, and path operations for the hapi ecosystem.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Safe data serialization utilities with error handling for JSON conversion operations, providing robust string representation of JavaScript values.
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 referencesJSON.stringify(): value, replacer, and space'[Cannot display object: <error description>]'JSON.stringify() for untrusted or complex data structures