v0.8.0 released — NLP Engine + Privacy Engine (PDP) modules for Indonesian text processing and UU PDP compliance. Read changelog
Skip to Content

Privacy Engine (PDP)

Indonesian PII (Personally Identifiable Information) scanning and masking utilities for UU PDP compliance.

Overview

The PDP module provides data-independent privacy utilities that scan and mask sensitive Indonesian PII:

  • NIK: Indonesian National Identity Number (16 digits)
  • NPWP: Taxpayer Identification Number
  • Phone: Indonesian phone numbers (mobile and landline)
  • Email: Email addresses
  • Passport: Indonesian passport numbers
  • BPJS: BPJS health/national insurance numbers
  • Bank Account: Generic bank account numbers

Features

  • Zero external dependencies (pure regex + algorithms)
  • Recursive object traversal for nested JSON
  • Cyclical reference detection (prevents infinite loops)
  • Confidence scoring for detections
  • JSON-safe escaping for logging
  • Partial or full masking strategies

Installation

npm install @indodev/toolkit

Quick Start

import { scanPII, maskStringPDP, anonymizePDP, anonymizeString } from '@indodev/toolkit/pdp'; // Scan for PII const findings = scanPII('NIK: 3171034567890123, HP: 081234567890'); // [{ type: 'nik', value: '3171034567890123', startIndex: 5, endIndex: 21, confidence: 'high' }, ...] // Mask in string maskStringPDP('NIK: 3171034567890123', { autoDetectPII: true }); // 'NIK: 3171********0123' // Anonymize JSON object anonymizePDP({ user: 'Budi', nik: '3171034567890123', email: 'budi@contoh.com' }, { autoDetectPII: true }); // { user: 'Budi', nik: '3171********0123', email: 'bu**@contoh.com' } // With escapeForLog for JSON-safe logging anonymizeString('Text with "quotes" and \\n newlines', { escapeForLog: true }); // 'Text with \"quotes\" and \\n newlines'

API Reference

scanPII()

Scans text for Indonesian PII and returns findings with position and confidence.

function scanPII(text: string): PIIFinding[];

Parameters:

NameTypeDescription
textstringText to scan

Returns: Array of PIIFinding objects sorted by position

Supported PII Types:

TypePatternConfidence
nik16 digitshigh
npwp15 digits with dotshigh
phone08xx or +62 prefixmedium
emailStandard email formatmedium
passportLetter + 6-8 digitslow
bpjs000 prefix or BPJS prefixlow
bank-account7-16 digitslow

Examples:

scanPII('NIK: 3171034567890123'); // [{ type: 'nik', value: '3171034567890123', startIndex: 5, endIndex: 21, confidence: 'high' }]

maskStringPDP()

Masks detected PII in a string without altering structure.

function maskStringPDP(text: string, options?: PIIOptions): string;

Parameters:

NameTypeDescription
textstringText containing PII
optionsPIIOptionsMasking options

Examples:

maskStringPDP('NIK: 3171034567890123', { autoDetectPII: true }); // 'NIK: 3171********0123' maskStringPDP('NIK: 3171034567890123', { maskChar: 'X', maskStrategy: 'full' }); // 'NIK: XXXXXXXXXXXXXXXX'

anonymizeString()

Masks PII and optionally escapes for JSON-safe logging.

function anonymizeString(text: string, options?: PIIOptions): string;

Examples:

anonymizeString('NIK: 3171034567890123', { autoDetectPII: true }); // 'NIK: 3171********0123' anonymizeString('Alert: injection\\ntest', { escapeForLog: true }); // 'Alert: injection\\\\ntest'

anonymizePDP()

Recursively anonymizes JSON objects with cyclical reference protection.

function anonymizePDP<T>(payload: T, options?: PIIOptions): T;

Examples:

const data = { user: 'Budi', nik: '3171034567890123', address: { phone: '02112345678' } }; anonymizePDP(data, { autoDetectPII: true }); // { user: 'Budi', nik: '3171********0123', address: { phone: '021****5678' } } // With cyclical reference const circular: any = { name: 'test' }; circular.self = circular; anonymizePDP(circular); // { name: 'test', self: '[Circular]' }

PIIOptions

interface PIIOptions { explicitKeys?: Array<string | RegExp>; autoDetectPII?: boolean; maskChar?: string; maskStrategy?: 'full' | 'partial'; replacementText?: string; escapeForLog?: boolean; }
OptionTypeDefaultDescription
explicitKeysArray<string | RegExp>[]Keys to always mask
autoDetectPIIbooleantrueAuto-detect PII types
maskCharstring'*'Character for masking
maskStrategy'full' | 'partial''partial'Partial preserves start/end
replacementTextstring''Custom replacement text
escapeForLogbooleanfalseEscape for JSON logging

Type Reference

PIIType

type PIIType = 'nik' | 'npwp' | 'phone' | 'email' | 'passport' | 'bpjs' | 'bank-account';

PIIFinding

interface PIIFinding { type: PIIType; value: string; startIndex: number; endIndex: number; confidence: 'high' | 'medium' | 'low'; }

PIIConfidence

type PIIConfidence = 'high' | 'medium' | 'low';
  • high: Valid format + checksum validation
  • medium: Valid format + prefix matched
  • low: Pattern match only

Edge Cases

CaseBehavior
Cyclical referencesReturns '[Circular]'
Deep nesting (>10 levels)Stops traversal
Null/undefinedReturns as-is
ArraysRecursively processes each element
Non-PII contentReturns unchanged
Empty stringReturns ''
  • NLP - Text processing utilities
  • NIK - NIK validation and parsing
  • Phone - Phone number utilities
Last updated on