CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sentry--utils

Deprecated utilities package for Sentry JavaScript SDKs - all functionality moved to @sentry/core

Pending
Overview
Eval results
Files

data-processing.mddocs/

Data Normalization & Processing

DEPRECATED: Import all functions from @sentry/core instead of @sentry/utils.

Data normalization and serialization utilities for preparing data structures for transmission, debugging, and storage while handling circular references and deep objects.

Capabilities

Core Normalization

Primary functions for normalizing complex data structures.

/**
 * Normalizes any input to a JSON-serializable format with depth and property limits
 * @param input - Any input value to normalize
 * @param depth - Maximum depth to traverse (default: 3)
 * @param maxProperties - Maximum number of properties to include (default: 1000)  
 * @returns Normalized, JSON-serializable version of the input
 */
function normalize(input: any, depth?: number, maxProperties?: number): any;

/**
 * Normalizes an object to fit within specified size constraints
 * @param object - Object to normalize
 * @param minSize - Minimum size in characters (default: 1024)
 * @param maxSize - Maximum size in characters (default: 64 * 1024)
 * @returns Normalized object that fits within size constraints
 */
function normalizeToSize(
  object: { [key: string]: any },
  minSize?: number,
  maxSize?: number,
): { [key: string]: any };

Usage Examples:

import { normalize, normalizeToSize } from "@sentry/core";

// Basic normalization with circular reference handling
const circularObj = { name: 'test' };
circularObj.self = circularObj;

const normalized = normalize(circularObj, 2);
// Result: { name: 'test', self: '[Circular ~]' }

// Size-constrained normalization for transmission
const largeObject = {
  users: Array(1000).fill(0).map((_, i) => ({
    id: i,
    name: `User ${i}`,
    data: 'x'.repeat(100)
  }))
};

const constrained = normalizeToSize(largeObject, 1024, 8192);
// Result: Truncated version that fits within 8KB

Object Manipulation

Functions for manipulating and transforming object structures.

/**
 * Converts any input to a plain object format
 * @param input - Input value to convert
 * @returns Plain object representation
 */
function convertToPlainObject(input: any): PlainObject;

/**
 * Removes all properties with undefined values from an object
 * @param inputValue - Object to clean
 * @returns Object with undefined properties removed
 */
function dropUndefinedKeys(inputValue: { [key: string]: any }): { [key: string]: any };

/**
 * Adds a non-enumerable property to an object
 * @param obj - Target object
 * @param name - Property name
 * @param value - Property value
 */
function addNonEnumerableProperty(obj: any, name: string, value: any): void;

/**
 * Converts any value to an object representation
 * @param wat - Value to objectify
 * @returns Object representation of the value
 */
function objectify(wat: unknown): { [key: string]: any };

Usage Examples:

import { 
  convertToPlainObject, 
  dropUndefinedKeys, 
  addNonEnumerableProperty,
  objectify 
} from "@sentry/core";

// Convert complex objects to plain objects
class CustomError extends Error {
  code = 'CUSTOM_ERROR';
  details = { severity: 'high' };
}

const error = new CustomError('Something failed');
const plainError = convertToPlainObject(error);
// Result: { name: 'CustomError', message: 'Something failed', code: 'CUSTOM_ERROR', details: {...} }

// Clean up API response data
const apiResponse = {
  id: 123,
  name: 'John',
  email: undefined,
  phone: null,
  address: undefined
};

const cleaned = dropUndefinedKeys(apiResponse);
// Result: { id: 123, name: 'John', phone: null }

// Add metadata without affecting enumeration
const data = { user: 'john', action: 'login' };
addNonEnumerableProperty(data, '__metadata', { timestamp: Date.now() });

console.log(Object.keys(data)); // ['user', 'action'] - metadata not included
console.log(data.__metadata);   // { timestamp: ... } - but still accessible

// Convert various types to objects for consistent handling
console.log(objectify('hello'));     // { '0': 'h', '1': 'e', '2': 'l', '3': 'l', '4': 'o' }
console.log(objectify([1, 2, 3]));   // { '0': 1, '1': 2, '2': 3 }
console.log(objectify(null));        // {}

Array Processing

Utilities for array manipulation and normalization.

/**
 * Converts any value to an array
 * @param wat - Value to convert to array
 * @returns Array representation of the value
 */
function arrayify(wat: unknown): any[];

/**
 * Flattens nested arrays to a single level
 * @param arr - Array to flatten (can contain nested arrays)
 * @returns Flattened array
 */
function flatten<T>(arr: ReadonlyArray<T | ReadonlyArray<T>>): T[];

Usage Examples:

import { arrayify, flatten } from "@sentry/core";

// Convert various types to arrays
console.log(arrayify('hello'));        // ['hello']
console.log(arrayify(42));             // [42]
console.log(arrayify([1, 2, 3]));      // [1, 2, 3]
console.log(arrayify(null));           // []

// Flatten nested arrays
const nested = [1, [2, 3], [4, [5, 6]], 7];
const flattened = flatten(nested);
// Result: [1, 2, 3, 4, 5, 6, 7]

// Practical use case: processing form data
function processFormFields(fields: unknown): string[] {
  const fieldArray = arrayify(fields);
  const flattened = flatten(fieldArray);
  return flattened.map(field => String(field));
}

String Processing

Utilities for string manipulation and normalization.

/**
 * Truncates a string to a maximum length with ellipsis
 * @param str - String to truncate
 * @param max - Maximum length (default: Infinity)
 * @returns Truncated string with ellipsis if needed
 */
function truncate(str: string, max?: number): string;

/**
 * Safely joins array elements with a separator, handling various types
 * @param arr - Array to join
 * @param separator - Separator string (default: ', ')
 * @returns Joined string
 */
function safeJoin(arr: any[], separator?: string): string;

/**
 * Extracts exception keys for creating error messages
 * @param ex - Exception object
 * @returns String representation of exception keys
 */
function extractExceptionKeysForMessage(ex: Exception): string;

/**
 * Escapes a string for safe use in regular expressions
 * @param str - String to escape
 * @returns Escaped string safe for RegExp constructor
 */
function escapeStringForRegex(str: string): string;

Usage Examples:

import { 
  truncate, 
  safeJoin, 
  escapeStringForRegex 
} from "@sentry/core";

// Truncate long strings for display
const longMessage = 'This is a very long error message that should be truncated';
const short = truncate(longMessage, 50);
// Result: 'This is a very long error message that should...'

// Safe array joining with mixed types
const mixedArray = ['hello', 42, null, undefined, { name: 'object' }];
const joined = safeJoin(mixedArray, ' | ');
// Result: 'hello | 42 | null | undefined | [object Object]'

// Escape user input for regex
const userSearch = 'user@example.com (primary)';
const escapedPattern = escapeStringForRegex(userSearch);
const regex = new RegExp(escapedPattern, 'i');

Data Processing Patterns

Event Data Preparation

Typical workflow for preparing event data for transmission:

import { 
  normalize, 
  normalizeToSize, 
  dropUndefinedKeys, 
  truncate 
} from "@sentry/core";

function prepareEventData(rawEvent: any): any {
  // Step 1: Clean up undefined values
  let event = dropUndefinedKeys(rawEvent);
  
  // Step 2: Normalize complex structures and handle circular references
  event = normalize(event, 5, 1000);
  
  // Step 3: Truncate long strings
  if (event.message) {
    event.message = truncate(event.message, 1000);
  }
  
  // Step 4: Ensure final size constraints
  event = normalizeToSize(event, 1024, 64 * 1024);
  
  return event;
}

Safe Object Processing

Pattern for safely processing unknown objects:

import { 
  convertToPlainObject, 
  isPlainObject, 
  objectify 
} from "@sentry/core";

function safeObjectProcessor(input: unknown): Record<string, any> {
  // Convert to plain object for safe processing
  const plainObj = convertToPlainObject(input);
  
  // Ensure we have a plain object to work with
  if (!isPlainObject(plainObj)) {
    return objectify(plainObj);
  }
  
  return plainObj;
}

Data Serialization Pipeline

Complete pipeline for serializing complex data:

import { 
  normalize, 
  flatten, 
  arrayify, 
  truncate,
  safeJoin 
} from "@sentry/core";

function createSerializationPipeline() {
  return {
    // Step 1: Normalize structure
    normalize: (data: any) => normalize(data, 3, 500),
    
    // Step 2: Flatten arrays if needed
    flattenArrays: (data: any) => {
      if (Array.isArray(data)) {
        return flatten(arrayify(data));
      }
      return data;
    },
    
    // Step 3: Truncate strings
    truncateStrings: (data: any) => {
      if (typeof data === 'string') {
        return truncate(data, 500);
      }
      if (Array.isArray(data)) {
        return data.map(item => 
          typeof item === 'string' ? truncate(item, 500) : item
        );
      }
      return data;
    },
    
    // Step 4: Create final string representation
    stringify: (data: any) => {
      if (Array.isArray(data)) {
        return safeJoin(data, ', ');
      }
      return JSON.stringify(data);
    }
  };
}

Types

interface PlainObject {
  [key: string]: any;
}

type Primitive = 
  | null 
  | undefined 
  | string 
  | number 
  | boolean 
  | symbol 
  | bigint;

Migration Note: All data processing functions have been moved from @sentry/utils to @sentry/core. Update your imports accordingly.

Install with Tessl CLI

npx tessl i tessl/npm-sentry--utils

docs

async-utilities.md

data-processing.md

envelopes.md

environment.md

error-handling.md

index.md

instrumentation.md

logging.md

stack-processing.md

type-guards.md

tile.json