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

pi_masking

v1.0.3

Published

A lightweight Node.js utility to mask sensitive fields in nested JavaScript objects for JSON format. This package recursively masks specified string fields in objects and arrays, ideal for protecting sensitive data like emails, PAN numbers, or phone numbe

Readme

secure-data-masker

A lightweight Node.js utility to mask sensitive fields in nested JavaScript objects for JSON format. This package recursively masks specified string fields in objects and arrays, ideal for protecting sensitive data like emails, PAN numbers, or phone numbers before logging or serializing to JSON.


🚀 Installation

npm install secure-data-masker

🔐 Features

- ✅ Recursively masks string fields in nested objects and arrays

- ✅ Supports both JSON and XML inputs

- ✅ Supports custom mask characters (e.g., *, #)

- ✅ Handles XML namespaces (e.g., xsd1:email)

- ✅ Validates input to ensure JSON-serializability

- ✅ Safe defaults to prevent unintended data exposure

- ✅ Lightweight with minimal dependencies (xml2js only)

- ✅ Async support with Promises

📦 Usage 

1. With JSON format.

const masker = require('secure-data-masker');

const information = {
  email: '[email protected]',
  pan_no: 'ABCDE1234F',
  guest: {
    phone_no: '9876543210'
  },
  users: [
    {
      email: '[email protected]',
      pan_no: 'ABCDE1234F',
      phone_no: '1234567890'
    },
    {
      email: '[email protected]',
      pan_no: 'ZZZZZ9999Z',
      phone_no: '9876543210'
    }
  ]
};

const maskOptions = {
  maskWith: '*',
  fields: ['email', 'pan_no']
};

const masked = masker.maskSensitiveDetails(information, maskOptions);
console.log(JSON.stringify(masked, null, 2));

Output:

{
  "email": "*****************",
  "pan_no": "**********",
  "guest": {
    "phone_no": "9876543210"
  },
  "users": [
    {
      "email": "*****************",
      "pan_no": "**********",
      "phone_no": "1234567890"
    },
    {
      "email": "*****************",
      "pan_no": "**********",
      "phone_no": "9876543210"
    }
  ]
}

2. With Non JSON format

Example 1:

import masker from 'secure-data-masker';

const information = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AvailabilitySearch>
  <xmlns>http://www.abc.com/WebServices/Xml</xmlns>
  <Authority>
    <Org>abcde</Org>
    <User>123abc</User>
    <Password>abcer456</Password>
    <Currency>INR</Currency>
    <Language>en</Language>
    <TestDebug>false</TestDebug>
    <Version>0.0</Version>
  </Authority>
  <Hotels>
    <Id>1234</Id>
  </Hotels>
  <HotelStayDetails>
    <ArrivalDate>2025-09-13</ArrivalDate>
    <Nationality>IN</Nationality>
    <Nights>1</Nights>
    <Room>
      <Guests>
        <Adult/>
      </Guests>
    </Room>
  </HotelStayDetails>
</AvailabilitySearch>`

const maskOptions = {
  maskWith: '*',
  fields: ['Org', 'Nationality', "Currency"],
  isJson: false
};

const maskedXml = await masker.maskSensitiveDetails(information, maskOptions);
console.log(maskedXml);

Output:

`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AvailabilitySearch>
  <xmlns>http://www.abc.com/WebServices/Xml</xmlns>
  <Authority>
    <Org>*****</Org>
    <User>123abc</User>
    <Password>abcer456</Password>
    <Currency>***</Currency>
    <Language>en</Language>
    <TestDebug>false</TestDebug>
    <Version>0.0</Version>
  </Authority>
  <Hotels>
    <Id>1234</Id>
  </Hotels>
  <HotelStayDetails>
    <ArrivalDate>2025-09-13</ArrivalDate>
    <Nationality>**</Nationality>
    <Nights>1</Nights>
    <Room>
      <Guests>
        <Adult/>
      </Guests>
    </Room>
  </HotelStayDetails>
</AvailabilitySearch>`


Example: 2

const information = 

`<soapenv:Envelope xmlns:soapenv="http://schemas.abc.org/soap/envelope/"       
xmlns:xsd="http://hotel.com/xsd"       
xmlns:xsd1="http://hotel.com/xsd">
    <soapenv:Header/>
    <soapenv:Body>
        <xsd:SearchHotelsRequest>
            <xsd1:loginDetails xsd1:email="[email protected]" xsd1:password="12abc"/>
            <xsd:criteria>
                <xsd1:checkIn>2025-06-20</xsd1:checkIn>
                <xsd1:checkOut>2025-06-24</xsd1:checkOut>
                <xsd1:clientNationality>IN</xsd1:clientNationality>
                <xsd1:hotelSelector>
                    <xsd1:hotelIds>
                        <xsd1:hotelId>9090</xsd1:hotelId>
                    </xsd1:hotelIds>
                </xsd1:hotelSelector>
                <xsd1:room xsd1:adults="1" xsd1:children="0" xsd1:seqNo="0"></xsd1:room>
                <xsd1:room xsd1:adults="1" xsd1:children="1" xsd1:seqNo="1">
                    <xsd1:childAge>5</xsd1:childAge>
                </xsd1:room>
            </xsd:criteria>
        </xsd:SearchHotelsRequest>
    </soapenv:Body>
</soapenv:Envelope>`


const maskOptions = {
  maskWith: "*", fields: [
    "xsd1:email", "xsd1:password"
  ],
  isJSON: false
}

Output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<soapenv:Envelope>
  <xmlns:soapenv>http://schemas.abc.org/soap/envelope/</xmlns:soapenv>
  <xmlns:xsd>http://hotel.com/xsd</xmlns:xsd>
  <xmlns:xsd1>http://hotel.com/xsd</xmlns:xsd1>
  <soapenv:Header/>
  <soapenv:Body>
    <xsd:SearchHotelsRequest>
      <xsd1:loginDetails>
        <xsd1:email>**************</xsd1:email>
        <xsd1:password>******</xsd1:password>
      </xsd1:loginDetails>
      <xsd:criteria>
        <xsd1:checkIn>2025-06-20</xsd1:checkIn>
        <xsd1:checkOut>2025-06-24</xsd1:checkOut>
        <xsd1:clientNationality>IN</xsd1:clientNationality>
        <xsd1:hotelSelector>
          <xsd1:hotelIds>
            <xsd1:hotelId>9090</xsd1:hotelId>
          </xsd1:hotelIds>
        </xsd1:hotelSelector>
        <xsd1:room>
          <xsd1:adults>1</xsd1:adults>
          <xsd1:children>0</xsd1:children>
          <xsd1:seqNo>0</xsd1:seqNo>
        </xsd1:room>
        <xsd1:room>
          <xsd1:adults>1</xsd1:adults>
          <xsd1:children>1</xsd1:children>
          <xsd1:seqNo>1</xsd1:seqNo>
          <xsd1:childAge>5</xsd1:childAge>
        </xsd1:room>
      </xsd:criteria>
    </xsd:SearchHotelsRequest>
  </soapenv:Body>
</soapenv:Envelope>

📘 API

maskSensitiveDetails(information, maskOptions)

Parameters:

1. information (Object | Array): A JSON-serializable object or array to be masked.

2. maskOptions (Object - Optional): Configuration object

2a. maskWith (string): Single character used for masking. Default: '*'

2b. fields (array): List of string field names to mask (e.g., ['email', 'pan_no'])

2c. isJson (boolean): Set to true for JSON input, false for non JSON.

Returns:

- Promise<Object|string>: Returns the masked JSON object or XML strin

⚠️ Throws

"Input must be a valid JSON-serializable object or array" – if input is not object or array

"Input is not JSON-serializable" – if input has circular refs or non-JSON-safe values

"maskOptions must be a non-array object" – if maskOptions is invalid

"maskWith must be a single-character string" – if maskWith is not a single char

"fields must be an array of strings" – if field names are not all strings

"Information input must be a string" (for Non JSON mode)

📌 Things Users Should Know

Default Behavior:

If maskOptions is not provided, { maskWith: '*', fields: [] } is used.

If maskWith is omitted, it defaults to '*'.

If fields is omitted, no fields are masked.

JSON Compatibility:

Input must be JSON-serializable (no functions, undefined, or circular references).

Non-serializable inputs will throw an error.

Security Considerations:

Always specify fields explicitly to avoid unintended data leaks.

Only string values are masked. Non-string values (e.g., numbers, objects, null) remain unchanged.

Limitations:

Field name matching is case-sensitive.

The input object is modified in-place. Make a deep copy beforehand if needed.

Non-object or non-array inputs will throw an error.

🧪 Example with Default Options

const masker = require('secure-data-masker');

const data = {
  email: '[email protected]',
  pan_no: 'ABCDE1234F'
};

const masked = masker.maskSensitiveDetails(data);
console.log(JSON.stringify(masked, null, 2));

Output:

{
  "email": "[email protected]",
  "pan_no": "ABCDE1234F"
}


🧩 Example with Custom Mask Character

const masker = require('secure-data-masker');

const data = {
  email: '[email protected]',
  pan_no: 'ABCDE1234F'
};

const maskOptions = {
  maskWith: '#',
  fields: ['email']
};

const masked = masker.maskSensitiveDetails(data, maskOptions);
console.log(JSON.stringify(masked, null, 2));

Output:

{
  "email": "#################",
  "pan_no": "ABCDE1234F"
}

📄 License : MIT