pii-sanitizer-js 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -0
- package/bin/cli.js +23 -0
- package/bun.lock +26 -0
- package/index.js +38 -0
- package/jsconfig.json +29 -0
- package/package.json +16 -0
- package/src/index.js +15 -0
- package/src/patterns.js +6 -0
- package/tests/sanitize.test.js +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# PII Sanitizer JS
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://www.npmjs.com/package/pii-sanitizer-js)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
A lightweight, high-performance utility for **detecting and anonymizing Personally Identifiable Information (PII)** in text.
|
|
8
|
+
|
|
9
|
+
Originally designed to sanitize prompts before they are sent to AI models (LLMs) or to clean log files before they are shared.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
* **Smart Detection**: Identifies emails, credit cards, IPv4 addresses, and phone numbers.
|
|
14
|
+
* **Developed with Bun**: Take advantage of the speed of the most modern runtime.
|
|
15
|
+
* **Dual Interface**: Use it as a library in your code or as a CLI tool in your terminal.
|
|
16
|
+
* **No Dependencies**: Native, lightweight, and secure code.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
You can install it using NPM or Bun:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Using NPM
|
|
24
|
+
npm install pii-sanitizer-js
|
|
25
|
+
|
|
26
|
+
# Using Bun
|
|
27
|
+
bun add pii-sanitizer-js
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
As a Library (API)
|
|
32
|
+
Ideal for integrating into your Node.js applications or backend processes.
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
import { sanitize } from ‘pii-sanitizer-js’;
|
|
36
|
+
|
|
37
|
+
const text = “Contact admin@mail.com or call +1 555-0199.”;
|
|
38
|
+
const sanitized = sanitize(text);
|
|
39
|
+
|
|
40
|
+
console.log(sanitized);
|
|
41
|
+
// Output: “Contact [HIDDEN_EMAIL] or call [HIDDEN_PHONE].”
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Why this project
|
|
45
|
+
|
|
46
|
+
This project arose from the need to protect data privacy when interacting with third-party services and Artificial Intelligence APIs. It demonstrates the implementation of advanced regular expressions and data flow management in Node.js/Bun environments.
|
|
47
|
+
|
|
48
|
+
## Author
|
|
49
|
+
|
|
50
|
+
* **Zenzzj**:
|
|
51
|
+
* Github: [@Zenzzj](https://github.com/zenzzj)
|
|
52
|
+
* Discord: zen_xp
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { sanitize } from '../src/index.js';
|
|
2
|
+
import readline from 'readline';
|
|
3
|
+
|
|
4
|
+
const rl = readline.createInterface({input: process.stdin, output: process.stdout, terminal: false});
|
|
5
|
+
|
|
6
|
+
console.log('Prompt Sanitizer');
|
|
7
|
+
console.log('Paste or type your text here to clean it up: ')
|
|
8
|
+
let input = '';
|
|
9
|
+
|
|
10
|
+
rl.on('line', (line) => {
|
|
11
|
+
if (line.trim() === '') {
|
|
12
|
+
rl.close();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
input += line + '\n'
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
rl.on('close', () => {
|
|
19
|
+
const result = sanitize(input);
|
|
20
|
+
console.log('\nSanitized Content');
|
|
21
|
+
console.log(result);
|
|
22
|
+
process.exit(0);
|
|
23
|
+
});
|
package/bun.lock
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "pii-sanitizer",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@types/bun": "latest",
|
|
9
|
+
},
|
|
10
|
+
"peerDependencies": {
|
|
11
|
+
"typescript": "^5",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
"packages": {
|
|
16
|
+
"@types/bun": ["@types/bun@1.3.5", "", { "dependencies": { "bun-types": "1.3.5" } }, "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w=="],
|
|
17
|
+
|
|
18
|
+
"@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="],
|
|
19
|
+
|
|
20
|
+
"bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="],
|
|
21
|
+
|
|
22
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
23
|
+
|
|
24
|
+
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
|
25
|
+
}
|
|
26
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const PATTERNS = {
|
|
2
|
+
EMAIL: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
|
|
3
|
+
CREDIT_CARD: /\b(?:\d[ -]*?){13,16}\b/g,
|
|
4
|
+
IPV4: /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g,
|
|
5
|
+
PHONE: /\b(?:\+?\d{1,3}[- ]?)?\(?\d{3}\)?[- ]?\d{3}[- ]?\d{4}\b/g
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function sanitize(text) {
|
|
9
|
+
let sanitizedText = text;
|
|
10
|
+
|
|
11
|
+
for (const [key, pattern] of Object.entries(PATTERNS)) {
|
|
12
|
+
sanitizedText = sanitizedText.replace(pattern, `[HIDDEN_${key}]`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return sanitizedText
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
import readline from 'readline';
|
|
19
|
+
const rl = readline.createInterface({input: process.stdin, output: process.stdout, terminal: false});
|
|
20
|
+
|
|
21
|
+
console.log('Prompt Sanitizer');
|
|
22
|
+
console.log('Paste or type your text here to clean it up: ')
|
|
23
|
+
let input = '';
|
|
24
|
+
|
|
25
|
+
rl.on('line', (line) => {
|
|
26
|
+
if (line.trim() === '') {
|
|
27
|
+
rl.close();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
input += line + '\n'
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
rl.on('close', () => {
|
|
34
|
+
const result = sanitize(input);
|
|
35
|
+
console.log('\nSanitized Content');
|
|
36
|
+
console.log(result);
|
|
37
|
+
process.exit(0);
|
|
38
|
+
});
|
package/jsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Environment setup & latest features
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "Preserve",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
"jsx": "react-jsx",
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
|
|
11
|
+
// Bundler mode
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
// Best practices
|
|
18
|
+
"strict": true,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedIndexedAccess": true,
|
|
22
|
+
"noImplicitOverride": true,
|
|
23
|
+
|
|
24
|
+
// Some stricter flags (disabled by default)
|
|
25
|
+
"noUnusedLocals": false,
|
|
26
|
+
"noUnusedParameters": false,
|
|
27
|
+
"noPropertyAccessFromIndexSignature": false
|
|
28
|
+
}
|
|
29
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pii-sanitizer-js",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A lightweight utility to sanitize PII from strings and prompts.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"pii-sanitize": "bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["privacy", "pii", "sanitizer", "security", "nlp"],
|
|
14
|
+
"author": "Zen_xP",
|
|
15
|
+
"license": "MIT"
|
|
16
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PATTERNS } from './patterns.js';
|
|
2
|
+
|
|
3
|
+
export function sanitize(text, options = {}) {
|
|
4
|
+
if (typeof text !== 'string') return '';
|
|
5
|
+
|
|
6
|
+
let sanitizedText = text;
|
|
7
|
+
const { placeholders = {} } = options;
|
|
8
|
+
|
|
9
|
+
for (const [key, pattern] of Object.entries(PATTERNS)) {
|
|
10
|
+
const label = placeholders[key] || `[HIDDEN_${key}]`;
|
|
11
|
+
sanitizedText = sanitizedText.replace(pattern, label);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return sanitizedText;
|
|
15
|
+
}
|
package/src/patterns.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const PATTERNS = {
|
|
2
|
+
EMAIL: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
|
|
3
|
+
CREDIT_CARD: /\b(?:\d[ -]*?){13,16}\b/g,
|
|
4
|
+
IPV4: /\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/g,
|
|
5
|
+
PHONE: /\b(?:\+?\d{1,3}[- ]?)?\(?\d{3}\)?[- ]?\d{3}[- ]?\d{4}\b/g
|
|
6
|
+
};
|
|
File without changes
|