npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nurv-llc/redact-it

v1.0.4

Published

A TypeScript library for redacting sensitive information from objects by matching property names

Readme

@nurv-llc/redact-it

A TypeScript library for redacting sensitive information from objects and arrays by matching property names against configurable filters.

CI npm version codecov TypeScript Code Style: Prettier License: MIT

Installation

npm install @nurv-llc/redact-it

Quick Start

import { redactIt } from '@nurv-llc/redact-it';

const userData = {
  name: 'John Doe',
  email: '[email protected]',
  phoneNumber: '555-123-4567',
  address: '123 Main St',
};

const redacted = redactIt(userData);
console.log(redacted);
// Output: {
//   name: 'John Doe',
//   email: '[REDACTED]',
//   phoneNumber: '[REDACTED]',
//   address: '[REDACTED]'
// }

More Examples

// Example with various PII types
const sensitiveData = {
  name: 'Jane Smith',
  email: '[email protected]',
  creditCard: '4111-1111-1111-1111',
  driverLicense: 'DL123456789',
  dateOfBirth: '1990-01-15',
  passport: 'US123456789',
  apiKey: 'sk_live_abc123xyz',
  ipAddress: '192.168.1.100',
  bankAccount: '12345678901',
  taxId: '12-3456789',
  medicalRecord: 'MRN987654321',
  nationalId: 'SSN123-45-6789'
};

const redacted = redactIt(sensitiveData);
console.log(redacted);
// Output: {
//   name: 'Jane Smith',
//   email: '[REDACTED]',
//   creditCard: '[REDACTED]',
//   driverLicense: '[REDACTED]',
//   dateOfBirth: '[REDACTED]',
//   passport: '[REDACTED]',
//   apiKey: '[REDACTED]',
//   ipAddress: '[REDACTED]',
//   bankAccount: '[REDACTED]',
//   taxId: '[REDACTED]',
//   medicalRecord: '[REDACTED]',
//   nationalId: '[REDACTED]'
// }

How It Works

redact-it searches for property names (keys) that match sensitive data patterns and replaces their values with redaction text. By default, it looks for properties that indicate:

  • Email addresses: email, emailAddress, userEmail, etc.
  • Phone numbers: phone, phoneNumber, mobile, cellPhone, etc.
  • Social Security Numbers: ssn, socialSecurityNumber, socialSecurity, etc.
  • Credit Card Information: creditCard, cardNumber, ccNumber, etc.
  • Driver's License: driverLicense, licenseNumber, dlNumber, etc.
  • Passport Information: passport, passportNumber, passportId, etc.
  • IP Addresses: ipAddress, clientIp, remoteIp, etc.
  • Passwords & Secrets: password, token, apiKey, secret, etc.
  • Bank Account Info: accountNumber, bankAccount, routingNumber, etc.
  • Date of Birth: dateOfBirth, birthDate, dob, etc.
  • Tax IDs: taxId, ein, taxpayerId, etc.
  • Medical Records: medicalRecord, mrn, patientId, etc.
  • National IDs: nationalId, citizenId, personalId, etc.

API Reference

redactIt(data, options?)

Redacts sensitive information from an object or array of objects.

Parameters:

  • data: Record<string, any> | Record<string, any>[] - The object or array to redact
  • options?: RedactOptions - Configuration options

Returns: The redacted data with the same structure as input

RedactOptions

interface RedactOptions {
  deepScan?: boolean; // Default: false
  caseSensitive?: boolean; // Default: false
  filters?: (FilterConfig | string)[];
  additionalFilters?: (FilterConfig | string)[];
}

FilterConfig

interface FilterConfig {
  search: string | RegExp; // Pattern to match property names
  replace?: string; // Replacement text (default: '[REDACTED]')
}

Configuration Options

deepScan (default: false)

Controls whether to recursively scan nested objects and arrays.

const data = {
  user: {
    email: '[email protected]',
    profile: {
      workEmail: '[email protected]',
    },
  },
};

// Default behavior - only top level
redactIt(data);
// Output: {
//   user: {
//     email: '[email protected]',
//     profile: { workEmail: '[email protected]' }
//   }
// }

// Deep scan enabled
redactIt(data, { deepScan: true });
// Output: {
//   user: {
//     email: '[REDACTED]',
//     profile: { workEmail: '[REDACTED]' }
//   }
// }

caseSensitive (default: false)

Controls whether property name matching is case-sensitive.

const data = {
  EMAIL: '[email protected]',
  email: '[email protected]',
  Phone: '555-0123',
};

// Case insensitive (default)
redactIt(data);
// Output: {
//   EMAIL: '[REDACTED]',
//   email: '[REDACTED]',
//   Phone: '[REDACTED]'
// }

// Case sensitive
redactIt(data, { caseSensitive: true });
// Output: {
//   EMAIL: '[email protected]',    // No match - EMAIL ≠ email
//   email: '[REDACTED]',          // Match
//   Phone: '555-0123'             // No match - Phone ≠ phone
// }

filters

Replace default filters entirely with custom ones.

const data = {
  email: '[email protected]',
  password: 'secret123',
  apiKey: 'abc-def-123',
};

redactIt(data, {
  filters: [
    { search: 'password', replace: '[HIDDEN]' },
    { search: /.*key.*$/i, replace: '[SECRET]' },
    'email', // Reference to default email filter
  ],
});
// Output: {
//   email: '[REDACTED]',
//   password: '[HIDDEN]',
//   apiKey: '[SECRET]'
// }

additionalFilters

Add custom filters while keeping default ones.

const data = {
  email: '[email protected]', // Matched by default email filter
  phone: '555-0123', // Matched by default phone filter
  password: 'secret123', // Matched by additional filter
  creditCard: '4111-1111-1111-1111',
};

redactIt(data, {
  additionalFilters: [
    { search: 'password', replace: '[HIDDEN]' },
    { search: /credit.*card/i, replace: '[PAYMENT_INFO]' },
  ],
});
// Output: {
//   email: '[REDACTED]',
//   phone: '[REDACTED]',
//   password: '[HIDDEN]',
//   creditCard: '[PAYMENT_INFO]'
// }

Advanced Examples

Working with Arrays

const users = [
  { name: 'John', email: '[email protected]', role: 'admin' },
  { name: 'Jane', mobile: '555-0123', role: 'user' },
];

const redacted = redactIt(users);
console.log(redacted);
// Output: [
//   { name: 'John', email: '[REDACTED]', role: 'admin' },
//   { name: 'Jane', mobile: '[REDACTED]', role: 'user' }
// ]

Complex Nested Structures

const complexData = {
  company: 'ACME Corp',
  employees: [
    {
      id: 1,
      profile: {
        name: 'John Doe',
        contactInfo: {
          email: '[email protected]',
          phone: '555-0001',
        },
      },
    },
    {
      id: 2,
      profile: {
        name: 'Jane Smith',
        contactInfo: {
          workEmail: '[email protected]',
          mobile: '555-0002',
        },
      },
    },
  ],
};

const redacted = redactIt(complexData, { deepScan: true });
console.log(redacted);
// Output: {
//   company: 'ACME Corp',
//   employees: [
//     {
//       id: 1,
//       profile: {
//         name: 'John Doe',
//         contactInfo: {
//           email: '[REDACTED]',
//           phone: '[REDACTED]'
//         }
//       }
//     },
//     {
//       id: 2,
//       profile: {
//         name: 'Jane Smith',
//         contactInfo: {
//           workEmail: '[REDACTED]',
//           mobile: '[REDACTED]'
//         }
//       }
//     }
//   ]
// }

Custom Regex Patterns

const data = {
  customerEmail: '[email protected]',
  internalEmail: '[email protected]',
  userPhone: '555-0123',
  emergencyContact: '911',
  apiToken: 'tok_abc123',
  refreshToken: 'ref_xyz789',
};

redactIt(data, {
  filters: [
    // Only match email properties ending with 'Email' (case insensitive)
    { search: /.*email$/i, replace: '[EMAIL_REDACTED]' },
    // Match any property containing 'token'
    { search: /.*token.*/i, replace: '[TOKEN_REDACTED]' },
    // Exact match for specific property
    { search: 'emergencyContact', replace: '[EMERGENCY_REDACTED]' },
  ],
});
// Output: {
//   customerEmail: '[EMAIL_REDACTED]',
//   internalEmail: '[EMAIL_REDACTED]',
//   userPhone: '555-0123',              // Not matched by custom filters
//   emergencyContact: '[EMERGENCY_REDACTED]',
//   apiToken: '[TOKEN_REDACTED]',
//   refreshToken: '[TOKEN_REDACTED]'
// }

Default Filters

The library includes sixteen built-in filters for common PII types:

| Filter | Pattern Examples | Matches | | ---------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------ | | email | /^.*email.*$/i | email, emailAddress, userEmail, contactEmail, etc. | | phone | /^.*(phone\|mobile\|cell\|telephone).*$/i | phone, mobile, cellPhone, telephone, etc. | | ssn | /^.*(ssn\|social.*security\|socialsecurity).*$/i | ssn, socialSecurityNumber, social_security, etc. | | creditCard | /^.*(credit.*card\|card.*number\|cc.*number).*$/i | creditCard, cardNumber, ccNumber, paymentCard, etc. | | driverLicense | /^.*(driver.*license\|license.*number\|dl.*number).*$/i | driverLicense, licenseNumber, dlNumber, drivingLicense, etc. | | passport | /^.*(passport\|passport.*number\|passport.*id).*$/i | passport, passportNumber, passportId, etc. | | ipAddress | /^.*(ip.*address\|client.*ip\|remote.*ip\|user.*ip).*$/i| ipAddress, clientIp, remoteIp, userIp, ip, etc. | | password | /^.*(password\|passwd\|pwd\|token\|secret).*$/i | password, token, apiKey, secret, authToken, accessToken, etc. | | bankAccount | /^.*(account.*number\|bank.*account\|routing.*number).*$/i| accountNumber, bankAccount, routingNumber, iban, etc. | | dateOfBirth | /^.*(date.*of.*birth\|birth.*date\|dob\|birthday).*$/i | dateOfBirth, birthDate, dob, birthday, etc. | | taxId | /^.*(tax.*id\|ein\|taxpayer.*id\|federal.*id).*$/i | taxId, ein, taxpayerId, federalId, taxNumber, etc. | | medicalRecord | /^.*(medical.*record\|mrn\|patient.*id\|health.*id).*$/i| medicalRecord, mrn, patientId, healthId, medicalNumber, etc. | | nationalId | /^.*(national.*id\|citizen.*id\|personal.*id).*$/i | nationalId, citizenId, personalId, governmentId, identityNumber, etc. | | address | /^.*((billing\|shipping\|mailing).*address\|address(line)?\d*\|street\|addr(line)?\d*\|apt\|apartment\|suite\|unit\|po.*box).*$/i | address, billingAddress, shippingAddress, addressLine1, streetAddress, aptNumber, poBox, etc. | | postalCode | /^.*((postal\|post).*(code\|zip)\|zip(?=(Code\|Postal\|Plus4\|PlusFour\|Id\|[_-]\|$\|\d))\|zipcode).*$/i | zip, zipCode, postalCode, postCode, zip_plus4, zipPostal, etc. | | securityAnswer | /^.*(security.*question\|security.*answer\|secret.*question\|secret.*answer\|mother.*maiden.*name).*$/i | securityQuestion, securityAnswer, secretQuestion, secretAnswer, motherMaidenName, etc. |

All filters are case-insensitive and match property names containing the specified patterns.

TypeScript Support

The library is written in TypeScript and includes full type definitions:

import { redactIt, RedactOptions, FilterConfig } from '@nurv-llc/redact-it';

// Type-safe options
const options: RedactOptions = {
  deepScan: true,
  caseSensitive: false,
  additionalFilters: [{ search: 'password', replace: '[HIDDEN]' }],
};

// Input and output maintain type structure
interface User {
  name: string;
  email: string;
  phone: string;
}

const user: User = {
  name: 'John',
  email: '[email protected]',
  phone: '555-0123',
};

const redactedUser: User = redactIt(user);

Error Handling

The library will throw errors for invalid configurations:

// Error: Unknown default filter
redactIt(data, { filters: ['invalidFilter'] });

// Error: Invalid filter configuration
redactIt(data, { filters: [{ search: null }] });

Performance Considerations

  • Circular References: The library handles circular references safely without infinite loops
  • Large Objects: For very large objects with deep nesting, consider using deepScan: false if you only need top-level redaction
  • Filter Complexity: Simple string filters are faster than complex regex patterns

License

MIT License - see LICENSE file for details.

Development

Prerequisites

  • Node.js 16.x or higher
  • npm 7.x or higher

Setup

git clone https://github.com/cyb3rsyph0n/redact-it.git
cd redact-it
npm install

Scripts

npm run build          # Build the project
npm run test           # Run tests
npm run test:coverage  # Run tests with coverage
npm run format         # Format code with Prettier
npm run format:check   # Check code formatting
npm run type-check     # Run TypeScript compiler check

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass (npm test)
  6. Format your code (npm run format)
  7. Commit your changes using conventional commits
  8. Push to the branch (git push origin feature/amazing-feature)
  9. Open a Pull Request

Support