@yellowsakura/js-pii-mask 0.8.93

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yellow Sakura
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,263 @@
1
+ # js-pii-mask
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue)](https://opensource.org/licenses/MIT)
4
+ [![TypeScript](https://shields.io/badge/TypeScript-3178C6?logo=TypeScript&logoColor=FFF&style=flat-square)](https://www.typescriptlang.org)
5
+ [![npm](https://img.shields.io/npm/v/@yellowsakura/js-pii-mask)](https://www.npmjs.com/package/@yellowsakura/js-pii-mask)
6
+
7
+ <img align="left" width="100px" src="docs/logo.webp">
8
+
9
+ Simple lightweight PII (Personally Identifiable Information) masking library for **TypeScript / JavaScript**.
10
+
11
+ It provides **regex-based detection and masking** of common PII patterns, inspired by [OpenAI's guardrails-js](https://github.com/openai/openai-guardrails-js), with a strong focus on **simplicity, predictability, and extensibility**.
12
+
13
+ > ⚠️ Heuristic-based detection: useful in practice, **not a compliance guarantee**.
14
+
15
+ ## Contents
16
+
17
+ 1. [Features](#features)
18
+ 2. [Installation and use](#installation-and-use)
19
+ 3. [Supported PII entities](#supported-pii-entities)
20
+ 4. [API reference](#api-reference)
21
+ 5. [How it works and recommended use cases](#how-it-works-and-recommended-use-cases)
22
+ 6. [Licences](#licences)
23
+
24
+ ## Features
25
+
26
+ - 🔎 Detects **35+ common PII types** (global + regional)
27
+ - 🧩 **Custom rules** for managing specific domains
28
+ - ⚡ Fast, dependency-free, sequential processing
29
+ - ❌ **Cannot**: Understand semantic context or perform deep NLP analysis
30
+ - 🔍 **Trade-offs**: Balanced for minimal false positives, but may miss some edge cases
31
+
32
+ This library is **pattern-based**.
33
+
34
+ **Works well for**:
35
+ - Structured formats (emails, credit cards, SSNs, IBANs, phone numbers)
36
+
37
+ **Does NOT**:
38
+ - Understand semantic context
39
+ - Detect unstructured personal data
40
+ - Perform NER or NLP
41
+ - Guarantee 100% accuracy
42
+
43
+ **Expect**:
44
+ - False positives (numbers matching known formats)
45
+ - False negatives (PII without clear patterns)
46
+
47
+ Always combine with **manual review, access controls, encryption, and legal validation** for sensitive use cases.
48
+
49
+ ## Installation and use
50
+
51
+ ```bash
52
+ npm install @yellowsakura/js-pii-mask
53
+ ```
54
+
55
+ Quick start:
56
+
57
+ For ESM:
58
+
59
+ ```ts
60
+ import { mask } from '@yellowsakura/js-pii-mask'
61
+
62
+ mask('Email: admin@example.com, SSN: 123-45-6789')
63
+ // → "Email: <EMAIL_ADDRESS>, SSN: <US_SSN>"
64
+
65
+ mask('Contact john@example.com or call +1-555-123-4567')
66
+ // → "Contact <EMAIL_ADDRESS> or call +1-<PHONE_NUMBER>"
67
+ ```
68
+
69
+ For CommonJS:
70
+
71
+ ```js
72
+ const { mask, FixedPIIEntity } = require('@yellowsakura/js-pii-mask');
73
+
74
+ mask('Email: admin@example.com, SSN: 123-45-6789')
75
+ // → "Email: <EMAIL_ADDRESS>, SSN: <US_SSN>"
76
+ ```
77
+
78
+ **Note:** all the following examples use **ESM syntax**.
79
+
80
+ ### Selective fixed rule
81
+
82
+ ```ts
83
+ import { mask, FixedPIIEntity } from '@yellowsakura/js-pii-mask'
84
+
85
+ // Mask only specific entity types
86
+ mask("Email: test@example.com, SSN: 123-45-6789", {
87
+ fixedPiiEntities: [FixedPIIEntity.EMAIL_ADDRESS]
88
+ })
89
+ // Output: "Email: <EMAIL_ADDRESS>, SSN: 123-45-6789"
90
+
91
+ // Mask only financial information
92
+ mask("Card: 1234-5678-9012-3456, Email: test@example.com", {
93
+ fixedPiiEntities: [FixedPIIEntity.CREDIT_CARD, FixedPIIEntity.US_BANK_NUMBER]
94
+ })
95
+ // Output: "Card: <CREDIT_CARD>, Email: test@example.com"
96
+ ```
97
+
98
+ ### Custom rules
99
+
100
+ Use custom rules for internal or domain-specific identifiers.
101
+
102
+ ```ts
103
+ import { mask } from '@yellowsakura/js-pii-mask'
104
+ import type { CustomRule } from '@yellowsakura/js-pii-mask'
105
+
106
+ const rules: CustomRule[] = [
107
+ { pattern: /EMP-\d{5}/g, replacement: 'EMPLOYEE_ID' },
108
+ { pattern: /TICKET-[A-Z0-9]{8}/gi, replacement: 'TICKET_ID' }
109
+ ]
110
+
111
+ mask('Employee EMP-12345 opened TICKET-ABC12345', { customRules: rules })
112
+ // → "Employee <EMPLOYEE_ID> opened <TICKET_ID>"
113
+ ```
114
+
115
+ > Custom rules are applied **before** built-in PII detection.
116
+
117
+ ### Custom + fixed rules
118
+
119
+ ```ts
120
+ import { mask, FixedPIIEntity } from '@yellowsakura/js-pii-mask'
121
+ import type { CustomRule } from '@yellowsakura/js-pii-mask'
122
+
123
+ mask('Employee EMP-12345 (email: john@company.com) submitted ticket', {
124
+ customRules: [
125
+ { pattern: /EMP-\d{5}/g, replacement: 'EMPLOYEE_ID' }
126
+ ],
127
+ fixedPiiEntities: [FixedPIIEntity.EMAIL_ADDRESS]
128
+ })
129
+ // Output: "Employee <EMPLOYEE_ID> (email: <EMAIL_ADDRESS>) submitted ticket"
130
+ ```
131
+
132
+ ## Supported PII entities
133
+
134
+ The library includes **35+ predefined patterns**, including:
135
+
136
+ ### Global
137
+ - EMAIL_ADDRESS
138
+ - PHONE_NUMBER
139
+ - CREDIT_CARD
140
+ - IP_ADDRESS (IPv4 / IPv6)
141
+ - IBAN_CODE
142
+ - URL
143
+ - DATE_TIME
144
+
145
+ ### Country-specific (examples)
146
+ - US: SSN, Passport, Bank Number, ITIN
147
+ - UK: NHS, NINO
148
+ - EU: IT Fiscal Code, VAT, PESEL, NIF/NIE
149
+ - APAC: Aadhaar, PAN, NRIC/FIN, TFN, Medicare
150
+
151
+ Some entities require **context keywords** (e.g. `CVV`, `BIC_SWIFT`) to reduce false positives.
152
+
153
+ For overlapping patterns, explicitly specify `fixedPiiEntities`, see [`src/pii-fixed-rules.ts`](./src/pii-fixed-rules.ts) for an exhaustive list.
154
+
155
+ ## API reference
156
+
157
+ ### `mask(text: string, options?: MaskOptions): string`
158
+
159
+ Main function to mask PII in text.
160
+
161
+ **Parameters:**
162
+ - `text: string` - The text to scan and mask
163
+ - `options?: MaskOptions` - Optional configuration object
164
+
165
+ **Mask options:**
166
+
167
+ ```ts
168
+ type MaskOptions = {
169
+ // Array of custom masking rules (always applied FIRST)
170
+ customRules?: CustomRule[]
171
+
172
+ // Array of specific fixed PII entities to detect (always applied AFTER custom rules)
173
+ // If empty or undefined, ALL fixed entities are checked
174
+ fixedPiiEntities?: FixedPIIEntity[]
175
+ }
176
+ ```
177
+
178
+ **Returns:**
179
+ - `string` - The masked text with PII replaced by `<REPLACED>` placeholders
180
+
181
+ ### `CustomRule` interface
182
+
183
+ ```ts
184
+ interface CustomRule {
185
+ // Regular expression pattern to match (should use global flag /g)
186
+ pattern: RegExp
187
+
188
+ // Replacement string (will be wrapped in < >)
189
+ replacement: string
190
+ }
191
+ ```
192
+
193
+ **Guidelines:**
194
+ - Always use global flag (`/g`) to match all occurrences
195
+ - Be specific to avoid matching unintended text
196
+ - Use word boundaries (`\b`) when appropriate
197
+ - Test thoroughly with representative data
198
+
199
+ **Examples:**
200
+ ```ts
201
+ // Good: Specific pattern with word boundaries
202
+ {
203
+ pattern: /\bEMP-\d{5}\b/g,
204
+ replacement: 'EMPLOYEE_ID'
205
+ }
206
+
207
+ // Good: Case-insensitive matching
208
+ {
209
+ pattern: /ticket-[a-z0-9]{8}/gi,
210
+ replacement: 'TICKET_ID'
211
+ }
212
+
213
+ // Warning: Too broad
214
+ {
215
+ pattern: /\d{5}/g, // Matches any 5 digits
216
+ replacement: 'NUMBER'
217
+ }
218
+ ```
219
+
220
+ ### `FixedPIIEntity` Enum
221
+
222
+ Enumeration of all predefined PII entity types. Import to specify which entities to detect:
223
+
224
+ ```ts
225
+ import { FixedPIIEntity } from '@yellowsakura/js-pii-mask'
226
+
227
+ mask(text, {
228
+ fixedPiiEntities: [
229
+ FixedPIIEntity.EMAIL_ADDRESS,
230
+ FixedPIIEntity.PHONE_NUMBER,
231
+ FixedPIIEntity.US_SSN
232
+ ]
233
+ })
234
+ ```
235
+
236
+ ## How it works and recommended use cases:
237
+
238
+ 1. Unicode normalization (NFKC, zero-width removal)
239
+ 2. Apply custom rules (in order)
240
+ 3. Apply fixed PII rules (all or selected)
241
+ 4. Replace matches inline
242
+
243
+ Deterministic, sequential, and predictable.
244
+
245
+ ## Use cases
246
+
247
+ ✅ Test / staging data anonymization
248
+ ✅ API response redaction
249
+ ✅ Preprocessing before third-party services (e.g. LLM)
250
+ ✅ Masking internal identifiers
251
+
252
+ ⚠️ Use with caution for:
253
+ - Legal, medical, or financial documents
254
+ - Automated compliance enforcement
255
+
256
+ ❌ Not suitable as a standalone compliance solution.
257
+
258
+ # License
259
+
260
+ The code is licensed under the [MIT](https://opensource.org/licenses/MIT) by [Yellow Sakura](https://www.yellowsakura.com), [support@yellowsakura.com](mailto:support@yellowsakura.com), see the LICENSE file.
261
+ For more details, please refer to the [project page](https://www.yellowsakura.com/en/projects/js-pii-mask).
262
+
263
+ This library is adapted from [OpenAI's guardrails-js](https://github.com/openai/openai-guardrails-js) PII detection patterns.
@@ -0,0 +1,45 @@
1
+ import { CustomRule } from './pii-custom-rules';
2
+ import { FixedPIIEntity } from './pii-fixed-rules';
3
+ export type { CustomRule } from './pii-custom-rules';
4
+ export { FixedPIIEntity } from './pii-fixed-rules';
5
+ /**
6
+ * Configuration options for the `mask` function.
7
+ *
8
+ * - customRules: Optional array of custom rules for masking text patterns.
9
+ * Each rule defines a regex pattern and its replacement string.
10
+ * - fixedPiiEntities: Optional array of predefined PII (Personally
11
+ * Identifiable Information) entities to mask in the input text.
12
+ *
13
+ * Both properties are optional.
14
+ */
15
+ type MaskOptions = {
16
+ customRules?: CustomRule[];
17
+ fixedPiiEntities?: FixedPIIEntity[];
18
+ };
19
+ /**
20
+ * Mask PII (Personally Identifiable Information) in text.
21
+ *
22
+ * Detects and replaces PII entities with placeholder tokens.
23
+ *
24
+ * @param text - The text to scan and mask
25
+ * @param options - Optional configuration object for masking rules,
26
+ * see .MaskOptions
27
+ *
28
+ * @returns The text with PII entities replaced by placeholders
29
+ *
30
+ * @example
31
+ * // Basic usage with default fixed rules
32
+ * mask("Contact me at john@example.com or call 555-123-4567")
33
+ * // Returns: "Contact me at <EMAIL_ADDRESS> or call <PHONE_NUMBER>"
34
+ *
35
+ * @example
36
+ * // With custom rules
37
+ * mask("My name is John Doe", {
38
+ * customRules: [
39
+ * { pattern: /John/gi, replacement: 'FIRST_NAME' },
40
+ * { pattern: /Doe/gi, replacement: 'LAST_NAME' }
41
+ * ]
42
+ * })
43
+ * // Returns: "My name is <FIRST_NAME> <LAST_NAME>"
44
+ */
45
+ export declare function mask(inputText: string, options?: MaskOptions): string;
@@ -0,0 +1,45 @@
1
+ import { CustomRule } from './pii-custom-rules';
2
+ import { FixedPIIEntity } from './pii-fixed-rules';
3
+ export type { CustomRule } from './pii-custom-rules';
4
+ export { FixedPIIEntity } from './pii-fixed-rules';
5
+ /**
6
+ * Configuration options for the `mask` function.
7
+ *
8
+ * - customRules: Optional array of custom rules for masking text patterns.
9
+ * Each rule defines a regex pattern and its replacement string.
10
+ * - fixedPiiEntities: Optional array of predefined PII (Personally
11
+ * Identifiable Information) entities to mask in the input text.
12
+ *
13
+ * Both properties are optional.
14
+ */
15
+ type MaskOptions = {
16
+ customRules?: CustomRule[];
17
+ fixedPiiEntities?: FixedPIIEntity[];
18
+ };
19
+ /**
20
+ * Mask PII (Personally Identifiable Information) in text.
21
+ *
22
+ * Detects and replaces PII entities with placeholder tokens.
23
+ *
24
+ * @param text - The text to scan and mask
25
+ * @param options - Optional configuration object for masking rules,
26
+ * see .MaskOptions
27
+ *
28
+ * @returns The text with PII entities replaced by placeholders
29
+ *
30
+ * @example
31
+ * // Basic usage with default fixed rules
32
+ * mask("Contact me at john@example.com or call 555-123-4567")
33
+ * // Returns: "Contact me at <EMAIL_ADDRESS> or call <PHONE_NUMBER>"
34
+ *
35
+ * @example
36
+ * // With custom rules
37
+ * mask("My name is John Doe", {
38
+ * customRules: [
39
+ * { pattern: /John/gi, replacement: 'FIRST_NAME' },
40
+ * { pattern: /Doe/gi, replacement: 'LAST_NAME' }
41
+ * ]
42
+ * })
43
+ * // Returns: "My name is <FIRST_NAME> <LAST_NAME>"
44
+ */
45
+ export declare function mask(inputText: string, options?: MaskOptions): string;
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ function e(e,t){if(!e||!t||t.length===0)return e;for(let n of t){if(!n.pattern||n.replacement===void 0)continue;e=e.replace(n.pattern,`<${n.replacement}>`)}return e}let t=function(e){return e.CREDIT_CARD=`CREDIT_CARD`,e.CRYPTO=`CRYPTO`,e.DATE_TIME=`DATE_TIME`,e.EMAIL_ADDRESS=`EMAIL_ADDRESS`,e.IBAN_CODE=`IBAN_CODE`,e.IP_ADDRESS=`IP_ADDRESS`,e.PHONE_NUMBER=`PHONE_NUMBER`,e.URL=`URL`,e.CVV=`CVV`,e.BIC_SWIFT=`BIC_SWIFT`,e.US_BANK_NUMBER=`US_BANK_NUMBER`,e.US_DRIVER_LICENSE=`US_DRIVER_LICENSE`,e.US_ITIN=`US_ITIN`,e.US_PASSPORT=`US_PASSPORT`,e.US_SSN=`US_SSN`,e.UK_NHS=`UK_NHS`,e.UK_NINO=`UK_NINO`,e.ES_NIF=`ES_NIF`,e.ES_NIE=`ES_NIE`,e.IT_FISCAL_CODE=`IT_FISCAL_CODE`,e.IT_DOCUMENT=`IT_DOCUMENT`,e.IT_VAT_CODE=`IT_VAT_CODE`,e.PL_PESEL=`PL_PESEL`,e.FI_PERSONAL_IDENTITY_CODE=`FI_PERSONAL_IDENTITY_CODE`,e.SG_NRIC_FIN=`SG_NRIC_FIN`,e.SG_UEN=`SG_UEN`,e.AU_ABN=`AU_ABN`,e.AU_ACN=`AU_ACN`,e.AU_TFN=`AU_TFN`,e.AU_MEDICARE=`AU_MEDICARE`,e.IN_PAN=`IN_PAN`,e.IN_AADHAAR=`IN_AADHAAR`,e.IN_VEHICLE_REGISTRATION=`IN_VEHICLE_REGISTRATION`,e.IN_VOTER=`IN_VOTER`,e.IN_PASSPORT=`IN_PASSPORT`,e.KR_RRN=`KR_RRN`,e}({});const n=[`(?:[sS][wW][iI][fF][tT])`,`(?:[bB][iI][cC])`,`(?:[bB][aA][nN][kK][\\s-]?[cC][oO][dD][eE])`,`(?:[sS][wW][iI][fF][tT][\\s-]?[cC][oO][dD][eE])`,`(?:[bB][iI][cC][\\s-]?[cC][oO][dD][eE])`].join(`|`),r=RegExp(`(?:${n})[:\\s=]+([A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?)\\b`,`g`),i={[t.CREDIT_CARD]:[/\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g],[t.CRYPTO]:[/\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/g],[t.DATE_TIME]:[/\b(0[1-9]|1[0-2])[/-](0[1-9]|[12]\d|3[01])[/-](19|20)\d{2}\b/g],[t.EMAIL_ADDRESS]:[/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,RegExp(`(?<=[?&=/])[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}`,`g`)],[t.IBAN_CODE]:[/\b[A-Z]{2}[0-9]{2}[A-Z0-9]{4}[0-9]{7}([A-Z0-9]?){0,16}\b/g],[t.IP_ADDRESS]:[/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/g,/\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b/g,/\b(?:[0-9a-fA-F]{1,4}:){1,7}:|:(?::[0-9a-fA-F]{1,4}){1,7}\b/g],[t.PHONE_NUMBER]:[/\b(\+\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g],[t.URL]:[/\bhttps?:\/\/(?:[-\w.])+(?::[0-9]+)?(?:\/(?:[\w/_.])*(?:\?(?:[\w&=%.])*)?(?:#(?:[\w.])*)?)?/g],[t.CVV]:[/\b(?:cvv|cvc|security\s*code|card\s*code)[\s:=]*[0-9]{3,4}\b/gi],[t.BIC_SWIFT]:[r],[t.US_BANK_NUMBER]:[/\b\d{8,17}\b/g],[t.US_DRIVER_LICENSE]:[/\b[A-Z]\d{7}\b/g],[t.US_ITIN]:[/\b9\d{2}-\d{2}-\d{4}\b/g],[t.US_PASSPORT]:[/\b[A-Z]\d{8}\b/g],[t.US_SSN]:[/\b\d{3}-\d{2}-\d{4}\b|\b\d{9}\b/g],[t.UK_NHS]:[/\b\d{3} \d{3} \d{4}\b/g],[t.UK_NINO]:[/\b[A-Z]{2}\d{6}[A-Z]\b/g],[t.ES_NIF]:[/\b\d{8}[A-Z]\b/g],[t.ES_NIE]:[/\b[XYZ]\d{7}[A-Z]\b/g],[t.IT_FISCAL_CODE]:[/\b[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]\b/g],[t.IT_DOCUMENT]:[/\b[A-Z]{2}\d{7}\b/g],[t.IT_VAT_CODE]:[/\bIT\d{11}\b/g],[t.PL_PESEL]:[/\b\d{11}\b/g],[t.FI_PERSONAL_IDENTITY_CODE]:[/\b\d{6}[+-A]\d{3}[A-Z0-9]\b/g],[t.SG_NRIC_FIN]:[/\b[A-Z]\d{7}[A-Z]\b/g],[t.SG_UEN]:[/\b\d{8}[A-Z]\b|\b\d{9}[A-Z]\b/g],[t.AU_ABN]:[/\b\d{2} \d{3} \d{3} \d{3}\b/g],[t.AU_ACN]:[/\b\d{3} \d{3} \d{3}\b/g],[t.AU_TFN]:[/\b\d{9}\b/g],[t.AU_MEDICARE]:[/\b\d{4} \d{5} \d{1}\b/g],[t.IN_PAN]:[/\b[A-Z]{5}\d{4}[A-Z]\b/g],[t.IN_AADHAAR]:[/\b\d{4} \d{4} \d{4}\b/g],[t.IN_VEHICLE_REGISTRATION]:[/\b[A-Z]{2}\d{2}[A-Z]{2}\d{4}\b/g],[t.IN_VOTER]:[/\b[A-Z]{3}\d{7}\b/g],[t.IN_PASSPORT]:[/\b[A-Z]\d{7}\b/g],[t.KR_RRN]:[/\b\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])-[1-4]\d{6}\b/g]};function a(e,n=Object.values(t)){if(!e)return e;for(let t of n){let n=i[t];if(!n||!n.length)continue;for(let r of n)e=e.replace(r,`<${t}>`)}return e}function o(e){if(!e)return e;let t=/(?:\u200B|\u200C|\u200D|\u2060|\uFEFF)/g;try{return e.normalize(`NFKC`).replace(t,``)}catch{return e.replace(t,``)}}function s(t,n){let{customRules:r=[],fixedPiiEntities:i=[]}=n||{},s=o(t);return r.length>0&&(s=e(s,r)),i.length>0?a(s,i):a(s)}exports.FixedPIIEntity=t,exports.mask=s;
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ function e(e,t){if(!e||!t||t.length===0)return e;for(let n of t){if(!n.pattern||n.replacement===void 0)continue;e=e.replace(n.pattern,`<${n.replacement}>`)}return e}let t=function(e){return e.CREDIT_CARD=`CREDIT_CARD`,e.CRYPTO=`CRYPTO`,e.DATE_TIME=`DATE_TIME`,e.EMAIL_ADDRESS=`EMAIL_ADDRESS`,e.IBAN_CODE=`IBAN_CODE`,e.IP_ADDRESS=`IP_ADDRESS`,e.PHONE_NUMBER=`PHONE_NUMBER`,e.URL=`URL`,e.CVV=`CVV`,e.BIC_SWIFT=`BIC_SWIFT`,e.US_BANK_NUMBER=`US_BANK_NUMBER`,e.US_DRIVER_LICENSE=`US_DRIVER_LICENSE`,e.US_ITIN=`US_ITIN`,e.US_PASSPORT=`US_PASSPORT`,e.US_SSN=`US_SSN`,e.UK_NHS=`UK_NHS`,e.UK_NINO=`UK_NINO`,e.ES_NIF=`ES_NIF`,e.ES_NIE=`ES_NIE`,e.IT_FISCAL_CODE=`IT_FISCAL_CODE`,e.IT_DOCUMENT=`IT_DOCUMENT`,e.IT_VAT_CODE=`IT_VAT_CODE`,e.PL_PESEL=`PL_PESEL`,e.FI_PERSONAL_IDENTITY_CODE=`FI_PERSONAL_IDENTITY_CODE`,e.SG_NRIC_FIN=`SG_NRIC_FIN`,e.SG_UEN=`SG_UEN`,e.AU_ABN=`AU_ABN`,e.AU_ACN=`AU_ACN`,e.AU_TFN=`AU_TFN`,e.AU_MEDICARE=`AU_MEDICARE`,e.IN_PAN=`IN_PAN`,e.IN_AADHAAR=`IN_AADHAAR`,e.IN_VEHICLE_REGISTRATION=`IN_VEHICLE_REGISTRATION`,e.IN_VOTER=`IN_VOTER`,e.IN_PASSPORT=`IN_PASSPORT`,e.KR_RRN=`KR_RRN`,e}({});const n=[`(?:[sS][wW][iI][fF][tT])`,`(?:[bB][iI][cC])`,`(?:[bB][aA][nN][kK][\\s-]?[cC][oO][dD][eE])`,`(?:[sS][wW][iI][fF][tT][\\s-]?[cC][oO][dD][eE])`,`(?:[bB][iI][cC][\\s-]?[cC][oO][dD][eE])`].join(`|`),r=RegExp(`(?:${n})[:\\s=]+([A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?)\\b`,`g`),i={[t.CREDIT_CARD]:[/\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g],[t.CRYPTO]:[/\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/g],[t.DATE_TIME]:[/\b(0[1-9]|1[0-2])[/-](0[1-9]|[12]\d|3[01])[/-](19|20)\d{2}\b/g],[t.EMAIL_ADDRESS]:[/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,RegExp(`(?<=[?&=/])[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}`,`g`)],[t.IBAN_CODE]:[/\b[A-Z]{2}[0-9]{2}[A-Z0-9]{4}[0-9]{7}([A-Z0-9]?){0,16}\b/g],[t.IP_ADDRESS]:[/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/g,/\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b/g,/\b(?:[0-9a-fA-F]{1,4}:){1,7}:|:(?::[0-9a-fA-F]{1,4}){1,7}\b/g],[t.PHONE_NUMBER]:[/\b(\+\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g],[t.URL]:[/\bhttps?:\/\/(?:[-\w.])+(?::[0-9]+)?(?:\/(?:[\w/_.])*(?:\?(?:[\w&=%.])*)?(?:#(?:[\w.])*)?)?/g],[t.CVV]:[/\b(?:cvv|cvc|security\s*code|card\s*code)[\s:=]*[0-9]{3,4}\b/gi],[t.BIC_SWIFT]:[r],[t.US_BANK_NUMBER]:[/\b\d{8,17}\b/g],[t.US_DRIVER_LICENSE]:[/\b[A-Z]\d{7}\b/g],[t.US_ITIN]:[/\b9\d{2}-\d{2}-\d{4}\b/g],[t.US_PASSPORT]:[/\b[A-Z]\d{8}\b/g],[t.US_SSN]:[/\b\d{3}-\d{2}-\d{4}\b|\b\d{9}\b/g],[t.UK_NHS]:[/\b\d{3} \d{3} \d{4}\b/g],[t.UK_NINO]:[/\b[A-Z]{2}\d{6}[A-Z]\b/g],[t.ES_NIF]:[/\b\d{8}[A-Z]\b/g],[t.ES_NIE]:[/\b[XYZ]\d{7}[A-Z]\b/g],[t.IT_FISCAL_CODE]:[/\b[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]\b/g],[t.IT_DOCUMENT]:[/\b[A-Z]{2}\d{7}\b/g],[t.IT_VAT_CODE]:[/\bIT\d{11}\b/g],[t.PL_PESEL]:[/\b\d{11}\b/g],[t.FI_PERSONAL_IDENTITY_CODE]:[/\b\d{6}[+-A]\d{3}[A-Z0-9]\b/g],[t.SG_NRIC_FIN]:[/\b[A-Z]\d{7}[A-Z]\b/g],[t.SG_UEN]:[/\b\d{8}[A-Z]\b|\b\d{9}[A-Z]\b/g],[t.AU_ABN]:[/\b\d{2} \d{3} \d{3} \d{3}\b/g],[t.AU_ACN]:[/\b\d{3} \d{3} \d{3}\b/g],[t.AU_TFN]:[/\b\d{9}\b/g],[t.AU_MEDICARE]:[/\b\d{4} \d{5} \d{1}\b/g],[t.IN_PAN]:[/\b[A-Z]{5}\d{4}[A-Z]\b/g],[t.IN_AADHAAR]:[/\b\d{4} \d{4} \d{4}\b/g],[t.IN_VEHICLE_REGISTRATION]:[/\b[A-Z]{2}\d{2}[A-Z]{2}\d{4}\b/g],[t.IN_VOTER]:[/\b[A-Z]{3}\d{7}\b/g],[t.IN_PASSPORT]:[/\b[A-Z]\d{7}\b/g],[t.KR_RRN]:[/\b\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])-[1-4]\d{6}\b/g]};function a(e,n=Object.values(t)){if(!e)return e;for(let t of n){let n=i[t];if(!n||!n.length)continue;for(let r of n)e=e.replace(r,`<${t}>`)}return e}function o(e){if(!e)return e;let t=/(?:\u200B|\u200C|\u200D|\u2060|\uFEFF)/g;try{return e.normalize(`NFKC`).replace(t,``)}catch{return e.replace(t,``)}}function s(t,n){let{customRules:r=[],fixedPiiEntities:i=[]}=n||{},s=o(t);return r.length>0&&(s=e(s,r)),i.length>0?a(s,i):a(s)}export{t as FixedPIIEntity,s as mask};
@@ -0,0 +1,56 @@
1
+ /**
2
+ * PII Custom Rules Engine
3
+ *
4
+ * This module provides a simple mechanism for applying user-defined masking rules
5
+ * to text content. Unlike fixed rules, custom rules are provided at runtime and
6
+ * allow users to mask domain-specific or organization-specific sensitive data.
7
+ */
8
+ /**
9
+ * Custom masking rule defined by the user.
10
+ *
11
+ * A custom rule consists of a regex pattern to match and a replacement string.
12
+ * The pattern should use the global flag (`g`) to match all occurrences.
13
+ */
14
+ export interface CustomRule {
15
+ pattern: RegExp;
16
+ replacement: string;
17
+ }
18
+ /**
19
+ * Apply custom masking rules to text.
20
+ *
21
+ * Rules are processed sequentially in the order they appear in the array.
22
+ * Each rule's pattern is matched against the text, and all matches are
23
+ * replaced with the corresponding replacement string.
24
+ *
25
+ * Processing Behavior
26
+ *
27
+ * - Sequential: Rules are applied one after another
28
+ * - Stateful: Later rules operate on text modified by earlier rules
29
+ * - No validation: Patterns are used as-is without checking
30
+ * - No overlap handling: First match wins
31
+ *
32
+ * @param text - The text to scan and mask
33
+ * @param rules - Array of custom masking rules to apply
34
+ *
35
+ * @returns The text with all custom rules applied
36
+ *
37
+ * @example
38
+ * // Basic usage
39
+ * const text = "Employee EMP-12345 logged in"
40
+ * const rules: CustomRule[] = [
41
+ * { pattern: /EMP-\d{5}/g, replacement: 'EMPLOYEE_ID' }
42
+ * ]
43
+ * applyCustomRules(text, rules)
44
+ * // Returns: "Employee <EMPLOYEE_ID> logged in"
45
+ *
46
+ * @example
47
+ * // Multiple rules
48
+ * const text2 = "Ticket T-123 assigned to EMP-99999"
49
+ * const rules2: CustomRule[] = [
50
+ * { pattern: /T-\d{3}/g, replacement: 'TICKET_ID' },
51
+ * { pattern: /EMP-\d{5}/g, replacement: 'EMPLOYEE_ID' }
52
+ * ]
53
+ * applyCustomRules(text2, rules2)
54
+ * // Returns: "Ticket <TICKET_ID> assigned to <EMPLOYEE_ID>"
55
+ */
56
+ export declare function applyCustomRules(text: string, rules: CustomRule[]): string;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * PII Custom Rules Engine
3
+ *
4
+ * This module provides a simple mechanism for applying user-defined masking rules
5
+ * to text content. Unlike fixed rules, custom rules are provided at runtime and
6
+ * allow users to mask domain-specific or organization-specific sensitive data.
7
+ */
8
+ /**
9
+ * Custom masking rule defined by the user.
10
+ *
11
+ * A custom rule consists of a regex pattern to match and a replacement string.
12
+ * The pattern should use the global flag (`g`) to match all occurrences.
13
+ */
14
+ export interface CustomRule {
15
+ pattern: RegExp;
16
+ replacement: string;
17
+ }
18
+ /**
19
+ * Apply custom masking rules to text.
20
+ *
21
+ * Rules are processed sequentially in the order they appear in the array.
22
+ * Each rule's pattern is matched against the text, and all matches are
23
+ * replaced with the corresponding replacement string.
24
+ *
25
+ * Processing Behavior
26
+ *
27
+ * - Sequential: Rules are applied one after another
28
+ * - Stateful: Later rules operate on text modified by earlier rules
29
+ * - No validation: Patterns are used as-is without checking
30
+ * - No overlap handling: First match wins
31
+ *
32
+ * @param text - The text to scan and mask
33
+ * @param rules - Array of custom masking rules to apply
34
+ *
35
+ * @returns The text with all custom rules applied
36
+ *
37
+ * @example
38
+ * // Basic usage
39
+ * const text = "Employee EMP-12345 logged in"
40
+ * const rules: CustomRule[] = [
41
+ * { pattern: /EMP-\d{5}/g, replacement: 'EMPLOYEE_ID' }
42
+ * ]
43
+ * applyCustomRules(text, rules)
44
+ * // Returns: "Employee <EMPLOYEE_ID> logged in"
45
+ *
46
+ * @example
47
+ * // Multiple rules
48
+ * const text2 = "Ticket T-123 assigned to EMP-99999"
49
+ * const rules2: CustomRule[] = [
50
+ * { pattern: /T-\d{3}/g, replacement: 'TICKET_ID' },
51
+ * { pattern: /EMP-\d{5}/g, replacement: 'EMPLOYEE_ID' }
52
+ * ]
53
+ * applyCustomRules(text2, rules2)
54
+ * // Returns: "Ticket <TICKET_ID> assigned to <EMPLOYEE_ID>"
55
+ */
56
+ export declare function applyCustomRules(text: string, rules: CustomRule[]): string;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * PII Detection and Masking - Fixed Rules Engine
3
+ *
4
+ * This module provides a simplified PII detection system based on fixed regex patterns.
5
+ * It is adapted from OpenAI's guardrails-js project with significant simplifications.
6
+ *
7
+ * Original Source:
8
+ * https://github.com/openai/openai-guardrails-js/blob/main/src/checks/pii.ts
9
+ *
10
+ * Key differences from original:
11
+ *
12
+ * 1. Simplified Architecture: Removed guardrail system infrastructure, blocking/tripwire
13
+ * functionality, and encoded PII detection (base64, hex, URL encoding)
14
+ *
15
+ * 2. Sequential Processing: Removed complex overlap detection and span deduplication.
16
+ * Entities are now processed sequentially, first match wins.
17
+ * This heuristic makes behavior more predictable but requires careful ordering of entity
18
+ * types when overlap is possible.
19
+ *
20
+ * 3. No Capture Groups: Removed group-based pattern matching (previously used for CVV
21
+ * and BIC_SWIFT). All patterns now match the entire entity directly.
22
+ *
23
+ * 4. Pure Masking Focus: Designed exclusively for text masking operations, not for
24
+ * validation or blocking.
25
+ *
26
+ * This is a "fixed rules engine", patterns are predefined and well-tested. Users who need
27
+ * flexibility should use custom rules rather than modifying these patterns.
28
+ *
29
+ * License:
30
+ *
31
+ * The original OpenAI guardrails-js project is licensed under the MIT License.
32
+ * Copyright (c) OpenAI
33
+ *
34
+ * This adapted version maintains the same MIT License.
35
+ *
36
+ * @see https://github.com/openai/openai-guardrails-js
37
+ */
38
+ /**
39
+ * Supported PII entity types for detection.
40
+ *
41
+ * These represent common personally identifiable information patterns across
42
+ * different regions and use cases. Each entity type maps to one or more regex
43
+ * patterns optimized for that specific format.
44
+ */
45
+ export declare enum FixedPIIEntity {
46
+ CREDIT_CARD = "CREDIT_CARD",
47
+ CRYPTO = "CRYPTO",
48
+ DATE_TIME = "DATE_TIME",
49
+ EMAIL_ADDRESS = "EMAIL_ADDRESS",
50
+ IBAN_CODE = "IBAN_CODE",
51
+ IP_ADDRESS = "IP_ADDRESS",
52
+ PHONE_NUMBER = "PHONE_NUMBER",
53
+ URL = "URL",
54
+ CVV = "CVV",
55
+ BIC_SWIFT = "BIC_SWIFT",
56
+ US_BANK_NUMBER = "US_BANK_NUMBER",
57
+ US_DRIVER_LICENSE = "US_DRIVER_LICENSE",
58
+ US_ITIN = "US_ITIN",
59
+ US_PASSPORT = "US_PASSPORT",
60
+ US_SSN = "US_SSN",
61
+ UK_NHS = "UK_NHS",
62
+ UK_NINO = "UK_NINO",
63
+ ES_NIF = "ES_NIF",
64
+ ES_NIE = "ES_NIE",
65
+ IT_FISCAL_CODE = "IT_FISCAL_CODE",
66
+ IT_DOCUMENT = "IT_DOCUMENT",
67
+ IT_VAT_CODE = "IT_VAT_CODE",
68
+ PL_PESEL = "PL_PESEL",
69
+ FI_PERSONAL_IDENTITY_CODE = "FI_PERSONAL_IDENTITY_CODE",
70
+ SG_NRIC_FIN = "SG_NRIC_FIN",
71
+ SG_UEN = "SG_UEN",
72
+ AU_ABN = "AU_ABN",
73
+ AU_ACN = "AU_ACN",
74
+ AU_TFN = "AU_TFN",
75
+ AU_MEDICARE = "AU_MEDICARE",
76
+ IN_PAN = "IN_PAN",
77
+ IN_AADHAAR = "IN_AADHAAR",
78
+ IN_VEHICLE_REGISTRATION = "IN_VEHICLE_REGISTRATION",
79
+ IN_VOTER = "IN_VOTER",
80
+ IN_PASSPORT = "IN_PASSPORT",
81
+ KR_RRN = "KR_RRN"
82
+ }
83
+ /**
84
+ * Apply fixed PII masking rules to text
85
+ *
86
+ * This function uses a sequential, non-overlapping approach:
87
+ *
88
+ * 1. Entities are processed in the order provided
89
+ * 2. Once text is masked, it won't be re-matched by subsequent patterns
90
+ * 3. No overlap detection or resolution is performed
91
+ *
92
+ * This design prioritizes predictability and performance over handling edge cases.
93
+ *
94
+ * If patterns might overlap (e.g., CREDIT_CARD vs US_BANK_NUMBER), place the
95
+ * more specific pattern first in the entities array to ensure it takes precedence.
96
+ *
97
+ * @param text - The text to scan and mask
98
+ * @param entities - List of PII entity types to detect
99
+ *
100
+ * @returns The text with PII entities replaced
101
+ *
102
+ * @example
103
+ * // Default behavior
104
+ * applyFixedRules("Email: test@example.com")
105
+ * // Returns: "Email: <EMAIL_ADDRESS>"
106
+ *
107
+ * // Specific entities only
108
+ * applyFixedRules(
109
+ * "Email: test@example.com, SSN: 123-45-6789",
110
+ * [FixedPIIEntity.EMAIL_ADDRESS]
111
+ * )
112
+ * // Returns: "Email: <EMAIL_ADDRESS>, SSN: 123-45-6789"
113
+ *
114
+ * // Priority ordering matters
115
+ * applyFixedRules(
116
+ * "1234567890123456",
117
+ * [FixedPIIEntity.CREDIT_CARD, FixedPIIEntity.US_BANK_NUMBER] // Credit card checked first
118
+ * )
119
+ * // Returns: "<CREDIT_CARD>"
120
+ */
121
+ export declare function applyFixedRules(text: string, entities?: FixedPIIEntity[]): string;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * PII Detection and Masking - Fixed Rules Engine
3
+ *
4
+ * This module provides a simplified PII detection system based on fixed regex patterns.
5
+ * It is adapted from OpenAI's guardrails-js project with significant simplifications.
6
+ *
7
+ * Original Source:
8
+ * https://github.com/openai/openai-guardrails-js/blob/main/src/checks/pii.ts
9
+ *
10
+ * Key differences from original:
11
+ *
12
+ * 1. Simplified Architecture: Removed guardrail system infrastructure, blocking/tripwire
13
+ * functionality, and encoded PII detection (base64, hex, URL encoding)
14
+ *
15
+ * 2. Sequential Processing: Removed complex overlap detection and span deduplication.
16
+ * Entities are now processed sequentially, first match wins.
17
+ * This heuristic makes behavior more predictable but requires careful ordering of entity
18
+ * types when overlap is possible.
19
+ *
20
+ * 3. No Capture Groups: Removed group-based pattern matching (previously used for CVV
21
+ * and BIC_SWIFT). All patterns now match the entire entity directly.
22
+ *
23
+ * 4. Pure Masking Focus: Designed exclusively for text masking operations, not for
24
+ * validation or blocking.
25
+ *
26
+ * This is a "fixed rules engine", patterns are predefined and well-tested. Users who need
27
+ * flexibility should use custom rules rather than modifying these patterns.
28
+ *
29
+ * License:
30
+ *
31
+ * The original OpenAI guardrails-js project is licensed under the MIT License.
32
+ * Copyright (c) OpenAI
33
+ *
34
+ * This adapted version maintains the same MIT License.
35
+ *
36
+ * @see https://github.com/openai/openai-guardrails-js
37
+ */
38
+ /**
39
+ * Supported PII entity types for detection.
40
+ *
41
+ * These represent common personally identifiable information patterns across
42
+ * different regions and use cases. Each entity type maps to one or more regex
43
+ * patterns optimized for that specific format.
44
+ */
45
+ export declare enum FixedPIIEntity {
46
+ CREDIT_CARD = "CREDIT_CARD",
47
+ CRYPTO = "CRYPTO",
48
+ DATE_TIME = "DATE_TIME",
49
+ EMAIL_ADDRESS = "EMAIL_ADDRESS",
50
+ IBAN_CODE = "IBAN_CODE",
51
+ IP_ADDRESS = "IP_ADDRESS",
52
+ PHONE_NUMBER = "PHONE_NUMBER",
53
+ URL = "URL",
54
+ CVV = "CVV",
55
+ BIC_SWIFT = "BIC_SWIFT",
56
+ US_BANK_NUMBER = "US_BANK_NUMBER",
57
+ US_DRIVER_LICENSE = "US_DRIVER_LICENSE",
58
+ US_ITIN = "US_ITIN",
59
+ US_PASSPORT = "US_PASSPORT",
60
+ US_SSN = "US_SSN",
61
+ UK_NHS = "UK_NHS",
62
+ UK_NINO = "UK_NINO",
63
+ ES_NIF = "ES_NIF",
64
+ ES_NIE = "ES_NIE",
65
+ IT_FISCAL_CODE = "IT_FISCAL_CODE",
66
+ IT_DOCUMENT = "IT_DOCUMENT",
67
+ IT_VAT_CODE = "IT_VAT_CODE",
68
+ PL_PESEL = "PL_PESEL",
69
+ FI_PERSONAL_IDENTITY_CODE = "FI_PERSONAL_IDENTITY_CODE",
70
+ SG_NRIC_FIN = "SG_NRIC_FIN",
71
+ SG_UEN = "SG_UEN",
72
+ AU_ABN = "AU_ABN",
73
+ AU_ACN = "AU_ACN",
74
+ AU_TFN = "AU_TFN",
75
+ AU_MEDICARE = "AU_MEDICARE",
76
+ IN_PAN = "IN_PAN",
77
+ IN_AADHAAR = "IN_AADHAAR",
78
+ IN_VEHICLE_REGISTRATION = "IN_VEHICLE_REGISTRATION",
79
+ IN_VOTER = "IN_VOTER",
80
+ IN_PASSPORT = "IN_PASSPORT",
81
+ KR_RRN = "KR_RRN"
82
+ }
83
+ /**
84
+ * Apply fixed PII masking rules to text
85
+ *
86
+ * This function uses a sequential, non-overlapping approach:
87
+ *
88
+ * 1. Entities are processed in the order provided
89
+ * 2. Once text is masked, it won't be re-matched by subsequent patterns
90
+ * 3. No overlap detection or resolution is performed
91
+ *
92
+ * This design prioritizes predictability and performance over handling edge cases.
93
+ *
94
+ * If patterns might overlap (e.g., CREDIT_CARD vs US_BANK_NUMBER), place the
95
+ * more specific pattern first in the entities array to ensure it takes precedence.
96
+ *
97
+ * @param text - The text to scan and mask
98
+ * @param entities - List of PII entity types to detect
99
+ *
100
+ * @returns The text with PII entities replaced
101
+ *
102
+ * @example
103
+ * // Default behavior
104
+ * applyFixedRules("Email: test@example.com")
105
+ * // Returns: "Email: <EMAIL_ADDRESS>"
106
+ *
107
+ * // Specific entities only
108
+ * applyFixedRules(
109
+ * "Email: test@example.com, SSN: 123-45-6789",
110
+ * [FixedPIIEntity.EMAIL_ADDRESS]
111
+ * )
112
+ * // Returns: "Email: <EMAIL_ADDRESS>, SSN: 123-45-6789"
113
+ *
114
+ * // Priority ordering matters
115
+ * applyFixedRules(
116
+ * "1234567890123456",
117
+ * [FixedPIIEntity.CREDIT_CARD, FixedPIIEntity.US_BANK_NUMBER] // Credit card checked first
118
+ * )
119
+ * // Returns: "<CREDIT_CARD>"
120
+ */
121
+ export declare function applyFixedRules(text: string, entities?: FixedPIIEntity[]): string;
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@yellowsakura/js-pii-mask",
3
+ "version": "0.8.93",
4
+ "description": "Simple and effective PII data masking library for TypeScript/JavaScript",
5
+ "keywords": [
6
+ "pii",
7
+ "mask",
8
+ "masking",
9
+ "data-privacy",
10
+ "privacy",
11
+ "gdpr",
12
+ "ccpa",
13
+ "anonymization",
14
+ "typescript",
15
+ "personal-data",
16
+ "sensitive-data"
17
+ ],
18
+ "homepage": "https://github.com/YellowSakura/js-pii-mask#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/YellowSakura/js-pii-mask/issues"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/YellowSakura/js-pii-mask.git"
25
+ },
26
+ "license": "MIT",
27
+ "author": "Yellow Sakura",
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "directories": {
31
+ "doc": "docs",
32
+ "test": "test"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "scripts": {
40
+ "build": "tsdown",
41
+ "dev": "tsdown --watch",
42
+ "quality": "eslint src *.ts",
43
+ "test": "jest",
44
+ "test:single": "jest -t"
45
+ },
46
+ "devDependencies": {
47
+ "@swc/jest": "^0.2.39",
48
+ "@types/jest": "^30.0.0",
49
+ "@typescript-eslint/eslint-plugin": "^8.51.0",
50
+ "@typescript-eslint/parser": "^8.51.0",
51
+ "eslint": "^9.39.0",
52
+ "jest": "^30.2.0",
53
+ "tsdown": "^0.2.0",
54
+ "typescript": "^5.9.3"
55
+ },
56
+ "engines": {
57
+ "node": ">=24.12.0"
58
+ },
59
+ "module": "./dist/index.mjs"
60
+ }