vestig 0.2.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.
Files changed (69) hide show
  1. package/dist/config.d.ts +19 -0
  2. package/dist/config.d.ts.map +1 -0
  3. package/dist/config.js +80 -0
  4. package/dist/config.js.map +1 -0
  5. package/dist/context/correlation.d.ts +26 -0
  6. package/dist/context/correlation.d.ts.map +1 -0
  7. package/dist/context/correlation.js +53 -0
  8. package/dist/context/correlation.js.map +1 -0
  9. package/dist/context/index.d.ts +20 -0
  10. package/dist/context/index.d.ts.map +1 -0
  11. package/dist/context/index.js +122 -0
  12. package/dist/context/index.js.map +1 -0
  13. package/dist/index.d.ts +22 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +27 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/levels.d.ts +14 -0
  18. package/dist/levels.d.ts.map +1 -0
  19. package/dist/levels.js +28 -0
  20. package/dist/levels.js.map +1 -0
  21. package/dist/logger.d.ts +82 -0
  22. package/dist/logger.d.ts.map +1 -0
  23. package/dist/logger.js +267 -0
  24. package/dist/logger.js.map +1 -0
  25. package/dist/runtime.d.ts +29 -0
  26. package/dist/runtime.d.ts.map +1 -0
  27. package/dist/runtime.js +72 -0
  28. package/dist/runtime.js.map +1 -0
  29. package/dist/transports/batch.d.ts +69 -0
  30. package/dist/transports/batch.d.ts.map +1 -0
  31. package/dist/transports/batch.js +157 -0
  32. package/dist/transports/batch.js.map +1 -0
  33. package/dist/transports/console.d.ts +27 -0
  34. package/dist/transports/console.d.ts.map +1 -0
  35. package/dist/transports/console.js +82 -0
  36. package/dist/transports/console.js.map +1 -0
  37. package/dist/transports/datadog.d.ts +57 -0
  38. package/dist/transports/datadog.d.ts.map +1 -0
  39. package/dist/transports/datadog.js +173 -0
  40. package/dist/transports/datadog.js.map +1 -0
  41. package/dist/transports/file.d.ts +59 -0
  42. package/dist/transports/file.d.ts.map +1 -0
  43. package/dist/transports/file.js +167 -0
  44. package/dist/transports/file.js.map +1 -0
  45. package/dist/transports/http.d.ts +49 -0
  46. package/dist/transports/http.d.ts.map +1 -0
  47. package/dist/transports/http.js +106 -0
  48. package/dist/transports/http.js.map +1 -0
  49. package/dist/types.d.ts +224 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +2 -0
  52. package/dist/types.js.map +1 -0
  53. package/dist/utils/buffer.d.ts +62 -0
  54. package/dist/utils/buffer.d.ts.map +1 -0
  55. package/dist/utils/buffer.js +110 -0
  56. package/dist/utils/buffer.js.map +1 -0
  57. package/dist/utils/error.d.ts +14 -0
  58. package/dist/utils/error.d.ts.map +1 -0
  59. package/dist/utils/error.js +92 -0
  60. package/dist/utils/error.js.map +1 -0
  61. package/dist/utils/sanitize-presets.d.ts +54 -0
  62. package/dist/utils/sanitize-presets.d.ts.map +1 -0
  63. package/dist/utils/sanitize-presets.js +245 -0
  64. package/dist/utils/sanitize-presets.js.map +1 -0
  65. package/dist/utils/sanitize.d.ts +75 -0
  66. package/dist/utils/sanitize.d.ts.map +1 -0
  67. package/dist/utils/sanitize.js +216 -0
  68. package/dist/utils/sanitize.js.map +1 -0
  69. package/package.json +76 -0
@@ -0,0 +1,54 @@
1
+ import type { SanitizeConfig, SanitizePreset } from '../types';
2
+ /**
3
+ * Common patterns for detecting sensitive data in strings
4
+ */
5
+ export declare const COMMON_PATTERNS: {
6
+ email: {
7
+ name: string;
8
+ pattern: RegExp;
9
+ replacement: (match: string) => string;
10
+ };
11
+ creditCard: {
12
+ name: string;
13
+ pattern: RegExp;
14
+ replacement: (match: string) => string;
15
+ };
16
+ jwt: {
17
+ name: string;
18
+ pattern: RegExp;
19
+ replacement: string;
20
+ };
21
+ ipv4: {
22
+ name: string;
23
+ pattern: RegExp;
24
+ replacement: string;
25
+ };
26
+ ipv6: {
27
+ name: string;
28
+ pattern: RegExp;
29
+ replacement: string;
30
+ };
31
+ ssn: {
32
+ name: string;
33
+ pattern: RegExp;
34
+ replacement: string;
35
+ };
36
+ phone: {
37
+ name: string;
38
+ pattern: RegExp;
39
+ replacement: string;
40
+ };
41
+ };
42
+ /**
43
+ * Preset configurations for different compliance requirements
44
+ */
45
+ export declare const PRESETS: Record<SanitizePreset, SanitizeConfig>;
46
+ /**
47
+ * Get a preset configuration by name
48
+ */
49
+ export declare function getPreset(name: SanitizePreset): SanitizeConfig;
50
+ /**
51
+ * Merge two sanitization configs
52
+ */
53
+ export declare function mergeConfigs(base: SanitizeConfig, override: Partial<SanitizeConfig>): SanitizeConfig;
54
+ //# sourceMappingURL=sanitize-presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-presets.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize-presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAmB,cAAc,EAAE,MAAM,UAAU,CAAA;AAE/E;;GAEG;AACH,eAAO,MAAM,eAAe;;;;6BAIL,MAAM;;;;;6BAUN,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Bc,CAAA;AAkI3C;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,cAAc,EAAE,cAAc,CA6C1D,CAAA;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,CAG9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC3B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,cAAc,CAQhB"}
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Common patterns for detecting sensitive data in strings
3
+ */
4
+ export const COMMON_PATTERNS = {
5
+ email: {
6
+ name: 'email',
7
+ pattern: /([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/g,
8
+ replacement: (match) => {
9
+ const [local, domain] = match.split('@');
10
+ if (!local || !domain)
11
+ return '[EMAIL]';
12
+ const maskedLocal = `${local.slice(0, 2)}***`;
13
+ return `${maskedLocal}@${domain}`;
14
+ },
15
+ },
16
+ creditCard: {
17
+ name: 'creditCard',
18
+ pattern: /\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/g,
19
+ replacement: (match) => {
20
+ const digits = match.replace(/[- ]/g, '');
21
+ return `****${digits.slice(-4)}`;
22
+ },
23
+ },
24
+ jwt: {
25
+ name: 'jwt',
26
+ pattern: /eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/g,
27
+ replacement: '[JWT_REDACTED]',
28
+ },
29
+ ipv4: {
30
+ name: 'ipv4',
31
+ pattern: /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/g,
32
+ replacement: '[IP_REDACTED]',
33
+ },
34
+ ipv6: {
35
+ name: 'ipv6',
36
+ pattern: /(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}/g,
37
+ replacement: '[IP_REDACTED]',
38
+ },
39
+ ssn: {
40
+ name: 'ssn',
41
+ pattern: /\b\d{3}[-]?\d{2}[-]?\d{4}\b/g,
42
+ replacement: '[SSN_REDACTED]',
43
+ },
44
+ phone: {
45
+ name: 'phone',
46
+ pattern: /\b(?:\+?1[-.]?)?\(?[0-9]{3}\)?[-.]?[0-9]{3}[-.]?[0-9]{4}\b/g,
47
+ replacement: '[PHONE_REDACTED]',
48
+ },
49
+ };
50
+ /**
51
+ * Field sets for different compliance levels
52
+ */
53
+ const FIELD_SETS = {
54
+ minimal: ['password', 'secret', 'token', 'key', 'apikey', 'api_key', 'api-key'],
55
+ default: [
56
+ 'password',
57
+ 'pass',
58
+ 'pwd',
59
+ 'secret',
60
+ 'token',
61
+ 'api_key',
62
+ 'apikey',
63
+ 'api-key',
64
+ 'access_token',
65
+ 'accesstoken',
66
+ 'refresh_token',
67
+ 'private_key',
68
+ 'privatekey',
69
+ 'credit_card',
70
+ 'creditcard',
71
+ 'card_number',
72
+ 'cvv',
73
+ 'ssn',
74
+ 'social_security',
75
+ 'authorization',
76
+ 'bearer',
77
+ 'session_id',
78
+ 'sessionid',
79
+ 'cookie',
80
+ 'auth',
81
+ ],
82
+ gdpr: [
83
+ // Personal identifiers
84
+ 'name',
85
+ 'first_name',
86
+ 'firstname',
87
+ 'last_name',
88
+ 'lastname',
89
+ 'full_name',
90
+ 'fullname',
91
+ 'email',
92
+ 'phone',
93
+ 'telephone',
94
+ 'mobile',
95
+ 'address',
96
+ 'street',
97
+ 'city',
98
+ 'zip',
99
+ 'postal_code',
100
+ 'country',
101
+ 'birthdate',
102
+ 'birth_date',
103
+ 'date_of_birth',
104
+ 'dob',
105
+ 'age',
106
+ 'gender',
107
+ 'nationality',
108
+ // Online identifiers
109
+ 'ip',
110
+ 'ip_address',
111
+ 'user_agent',
112
+ 'useragent',
113
+ 'device_id',
114
+ 'deviceid',
115
+ 'mac_address',
116
+ // Financial
117
+ 'iban',
118
+ 'bank_account',
119
+ 'account_number',
120
+ ],
121
+ hipaa: [
122
+ // PHI (Protected Health Information)
123
+ 'patient_id',
124
+ 'patientid',
125
+ 'medical_record',
126
+ 'mrn',
127
+ 'diagnosis',
128
+ 'condition',
129
+ 'treatment',
130
+ 'medication',
131
+ 'prescription',
132
+ 'insurance_id',
133
+ 'health_plan',
134
+ 'provider',
135
+ 'physician',
136
+ 'doctor',
137
+ // Biometric
138
+ 'fingerprint',
139
+ 'retina',
140
+ 'voice_print',
141
+ 'dna',
142
+ // Images
143
+ 'photo',
144
+ 'image',
145
+ 'xray',
146
+ 'mri',
147
+ 'scan',
148
+ ],
149
+ pciDss: [
150
+ // Primary Account Number (PAN)
151
+ 'pan',
152
+ 'card_number',
153
+ 'cardnumber',
154
+ 'credit_card',
155
+ 'creditcard',
156
+ 'debit_card',
157
+ 'card_num',
158
+ // Cardholder data
159
+ 'cardholder',
160
+ 'card_holder',
161
+ 'expiry',
162
+ 'expiration',
163
+ 'exp_date',
164
+ 'cvv',
165
+ 'cvc',
166
+ 'cvv2',
167
+ 'cvc2',
168
+ 'security_code',
169
+ 'pin',
170
+ 'pin_block',
171
+ // Track data
172
+ 'track1',
173
+ 'track2',
174
+ 'magnetic_stripe',
175
+ ],
176
+ };
177
+ /**
178
+ * Preset configurations for different compliance requirements
179
+ */
180
+ export const PRESETS = {
181
+ none: {
182
+ enabled: false,
183
+ fields: [],
184
+ patterns: [],
185
+ },
186
+ minimal: {
187
+ enabled: true,
188
+ fields: FIELD_SETS.minimal,
189
+ patterns: [],
190
+ },
191
+ default: {
192
+ enabled: true,
193
+ fields: FIELD_SETS.default,
194
+ patterns: [COMMON_PATTERNS.email, COMMON_PATTERNS.creditCard, COMMON_PATTERNS.jwt],
195
+ },
196
+ gdpr: {
197
+ enabled: true,
198
+ fields: [...FIELD_SETS.default, ...FIELD_SETS.gdpr],
199
+ patterns: [
200
+ COMMON_PATTERNS.email,
201
+ COMMON_PATTERNS.creditCard,
202
+ COMMON_PATTERNS.jwt,
203
+ COMMON_PATTERNS.ipv4,
204
+ COMMON_PATTERNS.ipv6,
205
+ COMMON_PATTERNS.phone,
206
+ ],
207
+ },
208
+ hipaa: {
209
+ enabled: true,
210
+ fields: [...FIELD_SETS.default, ...FIELD_SETS.gdpr, ...FIELD_SETS.hipaa],
211
+ patterns: [
212
+ COMMON_PATTERNS.email,
213
+ COMMON_PATTERNS.creditCard,
214
+ COMMON_PATTERNS.jwt,
215
+ COMMON_PATTERNS.ipv4,
216
+ COMMON_PATTERNS.ssn,
217
+ COMMON_PATTERNS.phone,
218
+ ],
219
+ },
220
+ 'pci-dss': {
221
+ enabled: true,
222
+ fields: [...FIELD_SETS.default, ...FIELD_SETS.pciDss],
223
+ patterns: [COMMON_PATTERNS.creditCard, COMMON_PATTERNS.jwt],
224
+ },
225
+ };
226
+ /**
227
+ * Get a preset configuration by name
228
+ */
229
+ export function getPreset(name) {
230
+ const preset = PRESETS[name];
231
+ return preset ?? PRESETS.default;
232
+ }
233
+ /**
234
+ * Merge two sanitization configs
235
+ */
236
+ export function mergeConfigs(base, override) {
237
+ return {
238
+ enabled: override.enabled ?? base.enabled,
239
+ fields: override.fields ? [...(base.fields ?? []), ...override.fields] : base.fields,
240
+ patterns: override.patterns ? [...(base.patterns ?? []), ...override.patterns] : base.patterns,
241
+ replacement: override.replacement ?? base.replacement,
242
+ depth: override.depth ?? base.depth,
243
+ };
244
+ }
245
+ //# sourceMappingURL=sanitize-presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-presets.js","sourceRoot":"","sources":["../../src/utils/sanitize-presets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import type { FieldMatcher, SanitizeConfig, SanitizePattern, SanitizePreset } from '../types';
2
+ /**
3
+ * Configurable sanitizer for PII and sensitive data
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * // Using a preset
8
+ * const sanitizer = Sanitizer.fromPreset('gdpr')
9
+ * const safe = sanitizer.sanitize({ email: 'user@example.com', password: 'secret' })
10
+ *
11
+ * // Custom configuration
12
+ * const sanitizer = new Sanitizer({
13
+ * fields: ['customSecret', { type: 'prefix', value: 'private_' }],
14
+ * patterns: [{ name: 'custom', pattern: /secret-\w+/g, replacement: '[SECRET]' }],
15
+ * })
16
+ * ```
17
+ */
18
+ export declare class Sanitizer {
19
+ private readonly config;
20
+ private readonly fieldSet;
21
+ private readonly fieldMatchers;
22
+ constructor(config?: SanitizeConfig);
23
+ /**
24
+ * Create a sanitizer from a preset
25
+ */
26
+ static fromPreset(preset: SanitizePreset): Sanitizer;
27
+ /**
28
+ * Create a sanitizer by merging a preset with custom config
29
+ */
30
+ static fromPresetWithOverrides(preset: SanitizePreset, overrides: Partial<SanitizeConfig>): Sanitizer;
31
+ /**
32
+ * Sanitize a value recursively
33
+ */
34
+ sanitize<T>(value: T): T;
35
+ /**
36
+ * Add a field to sanitize
37
+ */
38
+ addField(field: string | FieldMatcher): void;
39
+ /**
40
+ * Add a pattern to sanitize
41
+ */
42
+ addPattern(pattern: SanitizePattern): void;
43
+ /**
44
+ * Check if a field name should be sanitized
45
+ */
46
+ private isSensitiveField;
47
+ /**
48
+ * Match a field against a FieldMatcher
49
+ */
50
+ private matchField;
51
+ /**
52
+ * Apply patterns to sanitize a string
53
+ */
54
+ private sanitizeString;
55
+ /**
56
+ * Recursively sanitize a value
57
+ */
58
+ private sanitizeValue;
59
+ /**
60
+ * Get the current configuration
61
+ */
62
+ getConfig(): Readonly<Required<SanitizeConfig>>;
63
+ }
64
+ /**
65
+ * Sanitize a value using the default preset
66
+ * (Backwards compatible function)
67
+ */
68
+ export declare function sanitize(value: unknown, additionalFields?: string[], depth?: number): unknown;
69
+ /**
70
+ * Create a sanitizer function with custom fields
71
+ * (Backwards compatible function)
72
+ */
73
+ export declare function createSanitizer(additionalFields?: string[]): (value: unknown) => unknown;
74
+ export { COMMON_PATTERNS, getPreset, mergeConfigs, PRESETS } from './sanitize-presets';
75
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAa7F;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;gBAElC,MAAM,GAAE,cAAmB;IAsBvC;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS;IAIpD;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAC7B,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,SAAS;IAIZ;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAKxB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAS5C;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAI1C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAoBlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,OAAO,CAAC,aAAa;IAiCrB;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;CAG/C;AAKD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,gBAAgB,GAAE,MAAM,EAAO,EAAE,KAAK,SAAI,GAAG,OAAO,CAa5F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,GAAE,MAAM,EAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAS5F;AAGD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,216 @@
1
+ import { COMMON_PATTERNS, getPreset, mergeConfigs } from './sanitize-presets';
2
+ /**
3
+ * Default replacement string
4
+ */
5
+ const DEFAULT_REPLACEMENT = '[REDACTED]';
6
+ /**
7
+ * Default maximum recursion depth
8
+ */
9
+ const DEFAULT_MAX_DEPTH = 10;
10
+ /**
11
+ * Configurable sanitizer for PII and sensitive data
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Using a preset
16
+ * const sanitizer = Sanitizer.fromPreset('gdpr')
17
+ * const safe = sanitizer.sanitize({ email: 'user@example.com', password: 'secret' })
18
+ *
19
+ * // Custom configuration
20
+ * const sanitizer = new Sanitizer({
21
+ * fields: ['customSecret', { type: 'prefix', value: 'private_' }],
22
+ * patterns: [{ name: 'custom', pattern: /secret-\w+/g, replacement: '[SECRET]' }],
23
+ * })
24
+ * ```
25
+ */
26
+ export class Sanitizer {
27
+ config;
28
+ fieldSet;
29
+ fieldMatchers;
30
+ constructor(config = {}) {
31
+ this.config = {
32
+ enabled: config.enabled ?? true,
33
+ fields: config.fields ?? [],
34
+ patterns: config.patterns ?? [],
35
+ replacement: config.replacement ?? DEFAULT_REPLACEMENT,
36
+ depth: config.depth ?? DEFAULT_MAX_DEPTH,
37
+ };
38
+ // Separate simple fields from matchers for faster lookup
39
+ this.fieldSet = new Set();
40
+ this.fieldMatchers = [];
41
+ for (const field of this.config.fields) {
42
+ if (typeof field === 'string') {
43
+ this.fieldSet.add(field.toLowerCase());
44
+ }
45
+ else {
46
+ this.fieldMatchers.push(field);
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Create a sanitizer from a preset
52
+ */
53
+ static fromPreset(preset) {
54
+ return new Sanitizer(getPreset(preset));
55
+ }
56
+ /**
57
+ * Create a sanitizer by merging a preset with custom config
58
+ */
59
+ static fromPresetWithOverrides(preset, overrides) {
60
+ return new Sanitizer(mergeConfigs(getPreset(preset), overrides));
61
+ }
62
+ /**
63
+ * Sanitize a value recursively
64
+ */
65
+ sanitize(value) {
66
+ if (!this.config.enabled)
67
+ return value;
68
+ return this.sanitizeValue(value, 0);
69
+ }
70
+ /**
71
+ * Add a field to sanitize
72
+ */
73
+ addField(field) {
74
+ this.config.fields.push(field);
75
+ if (typeof field === 'string') {
76
+ this.fieldSet.add(field.toLowerCase());
77
+ }
78
+ else {
79
+ this.fieldMatchers.push(field);
80
+ }
81
+ }
82
+ /**
83
+ * Add a pattern to sanitize
84
+ */
85
+ addPattern(pattern) {
86
+ this.config.patterns.push(pattern);
87
+ }
88
+ /**
89
+ * Check if a field name should be sanitized
90
+ */
91
+ isSensitiveField(fieldName) {
92
+ const lower = fieldName.toLowerCase();
93
+ // Check simple field set
94
+ if (this.fieldSet.has(lower))
95
+ return true;
96
+ // Check field matchers
97
+ for (const matcher of this.fieldMatchers) {
98
+ if (this.matchField(lower, matcher))
99
+ return true;
100
+ }
101
+ return false;
102
+ }
103
+ /**
104
+ * Match a field against a FieldMatcher
105
+ */
106
+ matchField(fieldName, matcher) {
107
+ const value = matcher.caseSensitive ? matcher.value : matcher.value.toLowerCase();
108
+ const name = matcher.caseSensitive ? fieldName : fieldName.toLowerCase();
109
+ switch (matcher.type) {
110
+ case 'exact':
111
+ return name === value;
112
+ case 'prefix':
113
+ return name.startsWith(value);
114
+ case 'suffix':
115
+ return name.endsWith(value);
116
+ case 'contains':
117
+ return name.includes(value);
118
+ case 'regex':
119
+ return new RegExp(matcher.value, matcher.caseSensitive ? '' : 'i').test(fieldName);
120
+ default:
121
+ return false;
122
+ }
123
+ }
124
+ /**
125
+ * Apply patterns to sanitize a string
126
+ */
127
+ sanitizeString(value) {
128
+ let result = value;
129
+ for (const { pattern, replacement } of this.config.patterns) {
130
+ const rep = replacement ?? this.config.replacement;
131
+ if (typeof rep === 'function') {
132
+ result = result.replace(pattern, rep);
133
+ }
134
+ else {
135
+ result = result.replace(pattern, rep);
136
+ }
137
+ }
138
+ return result;
139
+ }
140
+ /**
141
+ * Recursively sanitize a value
142
+ */
143
+ sanitizeValue(value, depth) {
144
+ if (depth > this.config.depth)
145
+ return value;
146
+ // Handle null/undefined
147
+ if (value === null || value === undefined)
148
+ return value;
149
+ // Handle strings
150
+ if (typeof value === 'string') {
151
+ return this.sanitizeString(value);
152
+ }
153
+ // Handle arrays
154
+ if (Array.isArray(value)) {
155
+ return value.map((item) => this.sanitizeValue(item, depth + 1));
156
+ }
157
+ // Handle objects
158
+ if (typeof value === 'object') {
159
+ const result = {};
160
+ for (const [key, val] of Object.entries(value)) {
161
+ if (this.isSensitiveField(key)) {
162
+ result[key] = this.config.replacement;
163
+ }
164
+ else {
165
+ result[key] = this.sanitizeValue(val, depth + 1);
166
+ }
167
+ }
168
+ return result;
169
+ }
170
+ // Return primitives as-is
171
+ return value;
172
+ }
173
+ /**
174
+ * Get the current configuration
175
+ */
176
+ getConfig() {
177
+ return this.config;
178
+ }
179
+ }
180
+ // Default sanitizer instance using 'default' preset
181
+ const defaultSanitizer = Sanitizer.fromPreset('default');
182
+ /**
183
+ * Sanitize a value using the default preset
184
+ * (Backwards compatible function)
185
+ */
186
+ export function sanitize(value, additionalFields = [], depth = 0) {
187
+ if (additionalFields.length > 0) {
188
+ // Create custom sanitizer with additional fields
189
+ // Use 'contains' matcher for backwards compatibility (old behavior used includes())
190
+ const sanitizer = Sanitizer.fromPresetWithOverrides('default', {
191
+ fields: additionalFields.map((field) => ({
192
+ type: 'contains',
193
+ value: field,
194
+ })),
195
+ });
196
+ return sanitizer.sanitize(value);
197
+ }
198
+ return defaultSanitizer.sanitize(value);
199
+ }
200
+ /**
201
+ * Create a sanitizer function with custom fields
202
+ * (Backwards compatible function)
203
+ */
204
+ export function createSanitizer(additionalFields = []) {
205
+ const sanitizer = Sanitizer.fromPresetWithOverrides('default', {
206
+ // Use 'contains' matcher for backwards compatibility
207
+ fields: additionalFields.map((field) => ({
208
+ type: 'contains',
209
+ value: field,
210
+ })),
211
+ });
212
+ return (value) => sanitizer.sanitize(value);
213
+ }
214
+ // Re-export presets and patterns for convenience
215
+ export { COMMON_PATTERNS, getPreset, mergeConfigs, PRESETS } from './sanitize-presets';
216
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"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"}