@hackylabs/deep-redact 3.0.5 → 4.0.1

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 (49) hide show
  1. package/README.md +229 -106
  2. package/dist/adapters/console/index.cjs +74 -0
  3. package/dist/adapters/console/index.d.cts +22 -0
  4. package/dist/adapters/console/index.d.ts +22 -0
  5. package/dist/adapters/console/index.js +73 -0
  6. package/dist/index.cjs +2782 -0
  7. package/dist/index.d.cts +7 -0
  8. package/dist/index.d.ts +7 -0
  9. package/dist/index.js +2780 -55
  10. package/dist/node-console-sink-BnRUkAAr.cjs +19 -0
  11. package/dist/node-console-sink-DaQleNZ8.js +14 -0
  12. package/dist/public-Da0aARA9.d.cts +127 -0
  13. package/dist/public-Dw4ycNzO.d.ts +127 -0
  14. package/package.json +68 -106
  15. package/dist/index.mjs +0 -40
  16. package/dist/types/index.d.ts +0 -29
  17. package/dist/types/types.d.ts +0 -224
  18. package/dist/types/utils/TransformerRegistry.d.ts +0 -52
  19. package/dist/types/utils/index.d.ts +0 -131
  20. package/dist/types/utils/standardTransformers/bigint.d.ts +0 -2
  21. package/dist/types/utils/standardTransformers/date.d.ts +0 -2
  22. package/dist/types/utils/standardTransformers/error.d.ts +0 -2
  23. package/dist/types/utils/standardTransformers/index.d.ts +0 -9
  24. package/dist/types/utils/standardTransformers/map.d.ts +0 -2
  25. package/dist/types/utils/standardTransformers/regex.d.ts +0 -2
  26. package/dist/types/utils/standardTransformers/set.d.ts +0 -2
  27. package/dist/types/utils/standardTransformers/url.d.ts +0 -2
  28. package/dist/types.js +0 -2
  29. package/dist/types.mjs +0 -1
  30. package/dist/utils/TransformerRegistry.js +0 -100
  31. package/dist/utils/TransformerRegistry.mjs +0 -94
  32. package/dist/utils/index.js +0 -471
  33. package/dist/utils/index.mjs +0 -467
  34. package/dist/utils/standardTransformers/bigint.js +0 -10
  35. package/dist/utils/standardTransformers/bigint.mjs +0 -6
  36. package/dist/utils/standardTransformers/date.js +0 -9
  37. package/dist/utils/standardTransformers/date.mjs +0 -5
  38. package/dist/utils/standardTransformers/error.js +0 -16
  39. package/dist/utils/standardTransformers/error.mjs +0 -12
  40. package/dist/utils/standardTransformers/index.js +0 -38
  41. package/dist/utils/standardTransformers/index.mjs +0 -35
  42. package/dist/utils/standardTransformers/map.js +0 -9
  43. package/dist/utils/standardTransformers/map.mjs +0 -5
  44. package/dist/utils/standardTransformers/regex.js +0 -15
  45. package/dist/utils/standardTransformers/regex.mjs +0 -11
  46. package/dist/utils/standardTransformers/set.js +0 -9
  47. package/dist/utils/standardTransformers/set.mjs +0 -5
  48. package/dist/utils/standardTransformers/url.js +0 -9
  49. package/dist/utils/standardTransformers/url.mjs +0 -5
@@ -1,471 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_js_1 = require("./standardTransformers/index.js");
4
- const TransformerRegistry_js_1 = require("./TransformerRegistry.js");
5
- const defaultConfig = {
6
- stringTests: [],
7
- blacklistedKeys: [],
8
- fuzzyKeyMatch: false,
9
- caseSensitiveKeyMatch: true,
10
- retainStructure: false,
11
- remove: false,
12
- replaceStringByLength: false,
13
- replacement: '[REDACTED]',
14
- types: ['string'],
15
- transformers: index_js_1.standardTransformers,
16
- };
17
- class RedactorUtils {
18
- constructor(customConfig) {
19
- var _a;
20
- /**
21
- * The configuration for the redaction.
22
- * @private
23
- */
24
- this.config = defaultConfig;
25
- /**
26
- * The transformed blacklist keys of flat regex patterns and complex config objects
27
- * @private
28
- */
29
- this.blacklistedKeysTransformed = [];
30
- /**
31
- * The transformer registry for efficient transformer lookup
32
- * @private
33
- */
34
- this.transformerRegistry = new TransformerRegistry_js_1.TransformerRegistry();
35
- this.createTransformedBlacklistedKey = (key, customConfig) => {
36
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
37
- if (key instanceof RegExp) {
38
- return {
39
- key,
40
- fuzzyKeyMatch: (_a = customConfig.fuzzyKeyMatch) !== null && _a !== void 0 ? _a : defaultConfig.fuzzyKeyMatch,
41
- caseSensitiveKeyMatch: (_b = customConfig.caseSensitiveKeyMatch) !== null && _b !== void 0 ? _b : defaultConfig.caseSensitiveKeyMatch,
42
- retainStructure: (_c = customConfig.retainStructure) !== null && _c !== void 0 ? _c : defaultConfig.retainStructure,
43
- replacement: (_d = customConfig.replacement) !== null && _d !== void 0 ? _d : defaultConfig.replacement,
44
- replaceStringByLength: (_e = customConfig.replaceStringByLength) !== null && _e !== void 0 ? _e : defaultConfig.replaceStringByLength,
45
- remove: (_f = customConfig.remove) !== null && _f !== void 0 ? _f : defaultConfig.remove,
46
- };
47
- }
48
- if (typeof key === 'string') {
49
- return {
50
- key,
51
- fuzzyKeyMatch: (_g = customConfig.fuzzyKeyMatch) !== null && _g !== void 0 ? _g : defaultConfig.fuzzyKeyMatch,
52
- caseSensitiveKeyMatch: (_h = customConfig.caseSensitiveKeyMatch) !== null && _h !== void 0 ? _h : defaultConfig.caseSensitiveKeyMatch,
53
- retainStructure: (_j = customConfig.retainStructure) !== null && _j !== void 0 ? _j : defaultConfig.retainStructure,
54
- replacement: (_k = customConfig.replacement) !== null && _k !== void 0 ? _k : defaultConfig.replacement,
55
- replaceStringByLength: (_l = customConfig.replaceStringByLength) !== null && _l !== void 0 ? _l : defaultConfig.replaceStringByLength,
56
- remove: (_m = customConfig.remove) !== null && _m !== void 0 ? _m : defaultConfig.remove,
57
- };
58
- }
59
- return {
60
- fuzzyKeyMatch: (_p = (_o = key.fuzzyKeyMatch) !== null && _o !== void 0 ? _o : customConfig.fuzzyKeyMatch) !== null && _p !== void 0 ? _p : defaultConfig.fuzzyKeyMatch,
61
- caseSensitiveKeyMatch: (_r = (_q = key.caseSensitiveKeyMatch) !== null && _q !== void 0 ? _q : customConfig.caseSensitiveKeyMatch) !== null && _r !== void 0 ? _r : defaultConfig.caseSensitiveKeyMatch,
62
- retainStructure: (_t = (_s = key.retainStructure) !== null && _s !== void 0 ? _s : customConfig.retainStructure) !== null && _t !== void 0 ? _t : defaultConfig.retainStructure,
63
- replacement: (_v = (_u = key.replacement) !== null && _u !== void 0 ? _u : customConfig.replacement) !== null && _v !== void 0 ? _v : defaultConfig.replacement,
64
- replaceStringByLength: (_x = (_w = key.replaceStringByLength) !== null && _w !== void 0 ? _w : customConfig.replaceStringByLength) !== null && _x !== void 0 ? _x : defaultConfig.replaceStringByLength,
65
- remove: (_z = (_y = key.remove) !== null && _y !== void 0 ? _y : customConfig.remove) !== null && _z !== void 0 ? _z : defaultConfig.remove,
66
- key: key.key,
67
- };
68
- };
69
- /**
70
- * Applies transformers to a value
71
- * @param value - The value to transform
72
- * @param key - The key to check
73
- * @returns The transformed value
74
- * @private
75
- */
76
- this.applyTransformers = (value, key, referenceMap) => {
77
- return this.transformerRegistry.applyTransformers(value, key, referenceMap);
78
- };
79
- /**
80
- * Checks if a key should be redacted
81
- * @param key - The key to check
82
- * @returns Whether the key should be redacted
83
- * @private
84
- */
85
- this.shouldRedactKey = (key) => {
86
- return this.blacklistedKeysTransformed.some(config => {
87
- const pattern = config.key;
88
- if (pattern instanceof RegExp)
89
- return pattern.test(key);
90
- if (!config.fuzzyKeyMatch && !config.caseSensitiveKeyMatch)
91
- return key.toLowerCase().trim().replace(/[_-]/g, '') === pattern.toLowerCase().trim().replace(/[_-]/g, '');
92
- if (config.fuzzyKeyMatch && !config.caseSensitiveKeyMatch)
93
- return key.toLowerCase().trim().replace(/[_-]/g, '').includes(pattern.toLowerCase().trim().replace(/[_-]/g, ''));
94
- if (config.fuzzyKeyMatch && config.caseSensitiveKeyMatch)
95
- return key.includes(pattern);
96
- if (!config.fuzzyKeyMatch && config.caseSensitiveKeyMatch)
97
- return key === pattern;
98
- });
99
- };
100
- /**
101
- * Checks if a value should be redacted
102
- * @param value - The value to check
103
- * @param key - The key to check
104
- * @returns Whether the value should be redacted
105
- * @private
106
- */
107
- this.shouldRedactValue = (value, valueKey) => {
108
- if (!this.config.types.includes(typeof value))
109
- return false;
110
- return this.shouldRedactKey(valueKey);
111
- };
112
- /**
113
- * Redacts a value based on the key-specific config
114
- * @param value - The value to redact
115
- * @param key - The key to check
116
- * @param redactingParent - Whether the parent is being redacted
117
- * @returns The redacted value
118
- * @private
119
- */
120
- this.redactValue = (value, redactingParent, keyConfig) => {
121
- var _a, _b, _c, _d;
122
- if (!this.config.types.includes(typeof value))
123
- return { transformed: value, redactingParent };
124
- const remove = (_a = keyConfig === null || keyConfig === void 0 ? void 0 : keyConfig.remove) !== null && _a !== void 0 ? _a : this.config.remove;
125
- const replacement = (_b = keyConfig === null || keyConfig === void 0 ? void 0 : keyConfig.replacement) !== null && _b !== void 0 ? _b : this.config.replacement;
126
- const replaceStringByLength = (_c = keyConfig === null || keyConfig === void 0 ? void 0 : keyConfig.replaceStringByLength) !== null && _c !== void 0 ? _c : this.config.replaceStringByLength;
127
- const retainStructure = (_d = keyConfig === null || keyConfig === void 0 ? void 0 : keyConfig.retainStructure) !== null && _d !== void 0 ? _d : this.config.retainStructure;
128
- if (retainStructure && typeof value === 'object' && value !== null)
129
- return { transformed: value, redactingParent: true };
130
- if (remove)
131
- return { transformed: undefined, redactingParent };
132
- if (typeof replacement === 'function')
133
- return { transformed: replacement(value), redactingParent };
134
- return {
135
- redactingParent,
136
- transformed: (typeof value === 'string' && replaceStringByLength)
137
- ? replacement.toString().repeat(value.length)
138
- : replacement,
139
- };
140
- };
141
- /**
142
- * Traverses the raw value
143
- * @param raw - The raw value to traverse
144
- * @returns The transformed value
145
- */
146
- this.traverse = (raw) => {
147
- if (typeof raw === 'string') {
148
- const { transformed } = this.applyStringTransformations(raw, false);
149
- return transformed;
150
- }
151
- if (typeof raw !== 'object' || raw === null || this.requiresTransformers(raw))
152
- return this.applyTransformers(raw);
153
- const referenceMap = new WeakMap();
154
- const cleanedInput = this.replaceCircularReferences(raw);
155
- const { output, stack } = this.initialiseTraversal(cleanedInput);
156
- if (typeof cleanedInput === 'object' && cleanedInput !== null)
157
- referenceMap.set(cleanedInput, '');
158
- while (stack.length > 0) {
159
- const { parent, key, value, path, redactingParent: amRedactingParent, keyConfig } = stack.pop();
160
- let transformed = this.applyTransformers(value, key, referenceMap);
161
- let redactingParent = amRedactingParent;
162
- if (typeof transformed !== 'object' || transformed === null) {
163
- const primitiveResult = this.handlePrimitiveValue(transformed, key, amRedactingParent, keyConfig);
164
- redactingParent = primitiveResult.redactingParent;
165
- transformed = primitiveResult.transformed;
166
- if (typeof transformed === 'undefined')
167
- continue;
168
- }
169
- else {
170
- const objectResult = this.handleObjectValue(transformed, key, path, redactingParent, referenceMap, keyConfig);
171
- transformed = objectResult.transformed;
172
- stack.push(...objectResult.stack);
173
- }
174
- if (parent !== null && key !== null)
175
- parent[key] = transformed;
176
- }
177
- return output;
178
- };
179
- this.config = Object.assign(Object.assign({}, defaultConfig), customConfig);
180
- this.blacklistedKeysTransformed = ((_a = customConfig.blacklistedKeys) !== null && _a !== void 0 ? _a : []).map((key) => this.createTransformedBlacklistedKey(key, customConfig));
181
- this.setupTransformerRegistry(this.config.transformers);
182
- }
183
- /**
184
- * Sets up the transformer registry based on the configuration
185
- * @param transformers - The transformer configuration
186
- * @private
187
- */
188
- setupTransformerRegistry(transformers) {
189
- if (Array.isArray(transformers)) {
190
- transformers.forEach(transformer => { this.transformerRegistry.addFallbackTransformer(transformer); });
191
- }
192
- else {
193
- const organised = transformers;
194
- if (organised.byType) {
195
- Object.entries(organised.byType).forEach(([type, typeTransformers]) => {
196
- if (typeTransformers) {
197
- typeTransformers.forEach(transformer => {
198
- this.transformerRegistry.addTypeTransformer(type, transformer);
199
- });
200
- }
201
- });
202
- }
203
- if (organised.byConstructor) {
204
- Object.entries(organised.byConstructor).forEach(([constructorName, constructorTransformers]) => {
205
- if (constructorTransformers) {
206
- const constructorMap = {
207
- Date,
208
- Error,
209
- Map,
210
- Set,
211
- RegExp,
212
- URL,
213
- };
214
- const constructor = constructorMap[constructorName];
215
- if (constructor) {
216
- constructorTransformers.forEach(transformer => {
217
- this.transformerRegistry.addConstructorTransformer(constructor, transformer);
218
- });
219
- }
220
- }
221
- });
222
- }
223
- }
224
- }
225
- /**
226
- * Applies string transformations
227
- * @param value - The value to transform
228
- * @param key - The key to check
229
- * @returns The transformed value
230
- * @private
231
- */
232
- applyStringTransformations(value, amRedactingParent, keyConfig) {
233
- var _a;
234
- if (((_a = this.config.stringTests) !== null && _a !== void 0 ? _a : []).length === 0)
235
- return { transformed: value, redactingParent: amRedactingParent };
236
- for (const test of this.config.stringTests) {
237
- if (test instanceof RegExp) {
238
- if (test.test(value)) {
239
- const { transformed, redactingParent } = this.redactValue(value, amRedactingParent, keyConfig);
240
- return { transformed: transformed, redactingParent };
241
- }
242
- }
243
- else {
244
- if (test.pattern.test(value)) {
245
- const transformed = test.replacer(value, test.pattern);
246
- return { transformed, redactingParent: amRedactingParent };
247
- }
248
- }
249
- }
250
- return { transformed: value, redactingParent: amRedactingParent };
251
- }
252
- /**
253
- * Handles primitive values
254
- * @param value - The value to handle
255
- * @param key - The key to check
256
- * @param redactingParent - Whether the parent is being redacted
257
- * @param keyConfig - The key config
258
- * @returns The transformed value
259
- * @private
260
- */
261
- handlePrimitiveValue(value, valueKey, redactingParent, keyConfig) {
262
- let transformed = value;
263
- if (redactingParent) {
264
- if (valueKey === '_transformer' || !this.config.types.includes(typeof value)) {
265
- return { transformed: value, redactingParent };
266
- }
267
- const { transformed: transformedValue } = this.redactValue(value, redactingParent, keyConfig);
268
- return { transformed: transformedValue, redactingParent };
269
- }
270
- if (keyConfig || this.shouldRedactValue(value, valueKey)) {
271
- return this.redactValue(value, redactingParent, keyConfig);
272
- }
273
- if (typeof value === 'string') {
274
- return this.applyStringTransformations(value, redactingParent, keyConfig);
275
- }
276
- return { transformed, redactingParent };
277
- }
278
- /**
279
- * Handles object values
280
- * @param value - The value to handle
281
- * @param key - The key to check
282
- * @param path - The path to the value
283
- * @param redactingParent - Whether the parent is being redacted
284
- * @param referenceMap - The reference map
285
- * @returns The transformed value and stack
286
- * @private
287
- */
288
- handleObjectValue(value, key, path, amRedactingParent, referenceMap, keyConfig) {
289
- var _a;
290
- const fullPath = path.join('.');
291
- const shouldRedact = amRedactingParent || Boolean(keyConfig) || this.shouldRedactValue(value, key);
292
- referenceMap.set(value, fullPath);
293
- if (shouldRedact && !((_a = keyConfig === null || keyConfig === void 0 ? void 0 : keyConfig.retainStructure) !== null && _a !== void 0 ? _a : this.config.retainStructure)) {
294
- const { transformed, redactingParent } = this.redactValue(value, amRedactingParent, keyConfig);
295
- return { transformed, redactingParent, stack: [] };
296
- }
297
- return this.handleRetainStructure(value, path, shouldRedact);
298
- }
299
- /**
300
- * Handles object values
301
- * @param value - The value to handle
302
- * @param path - The path to the value
303
- * @param redactingParent - Whether the parent is being redacted
304
- * @returns The transformed value and stack
305
- * @private
306
- */
307
- handleRetainStructure(value, path, redactingParent) {
308
- const newValue = Array.isArray(value) ? [] : {};
309
- const stack = [];
310
- if (Array.isArray(value)) {
311
- for (let i = value.length - 1; i >= 0; i--) {
312
- stack.push({
313
- parent: newValue,
314
- key: i.toString(),
315
- value: value[i],
316
- path: [...path, i],
317
- redactingParent,
318
- keyConfig: this.findMatchingKeyConfig(i.toString()),
319
- });
320
- }
321
- }
322
- else {
323
- for (const [propKey, propValue] of Object.entries(value).reverse()) {
324
- stack.push({
325
- parent: newValue,
326
- key: propKey,
327
- value: propValue,
328
- path: [...path, propKey],
329
- redactingParent,
330
- keyConfig: this.findMatchingKeyConfig(propKey),
331
- });
332
- }
333
- }
334
- return { transformed: newValue, redactingParent, stack };
335
- }
336
- /**
337
- * Finds the matching key config
338
- * @param key - The key to find
339
- * @returns The matching key config
340
- * @private
341
- */
342
- findMatchingKeyConfig(key) {
343
- return this.blacklistedKeysTransformed.find(config => {
344
- const pattern = config.key;
345
- if (pattern instanceof RegExp)
346
- return pattern.test(key);
347
- const normalisedKey = key.toLowerCase().trim().replace(/[_-]/g, '');
348
- const normalisedPattern = pattern.toLowerCase().trim().replace(/[_-]/g, '');
349
- if (config.fuzzyKeyMatch) {
350
- const compareKey = config.caseSensitiveKeyMatch ? key : normalisedKey;
351
- const comparePattern = config.caseSensitiveKeyMatch ? pattern : normalisedPattern;
352
- return compareKey.includes(comparePattern);
353
- }
354
- return config.caseSensitiveKeyMatch ? key === pattern : normalisedKey === normalisedPattern;
355
- });
356
- }
357
- /**
358
- * Initialises the traversal
359
- * @param raw - The raw value to traverse
360
- * @returns The output and stack
361
- * @private
362
- */
363
- initialiseTraversal(raw) {
364
- const output = Array.isArray(raw) ? [] : {};
365
- const stack = [];
366
- if (typeof raw === 'object' && raw !== null) {
367
- if (Array.isArray(raw)) {
368
- for (let i = raw.length - 1; i >= 0; i--) {
369
- stack.push({
370
- parent: output,
371
- key: i.toString(),
372
- value: raw[i],
373
- path: [i],
374
- redactingParent: false,
375
- keyConfig: this.findMatchingKeyConfig(i.toString()),
376
- });
377
- }
378
- }
379
- else {
380
- for (const [propKey, propValue] of Object.entries(raw).reverse()) {
381
- stack.push({
382
- parent: output,
383
- key: propKey,
384
- value: propValue,
385
- path: [propKey],
386
- redactingParent: false,
387
- keyConfig: this.findMatchingKeyConfig(propKey),
388
- });
389
- }
390
- }
391
- }
392
- return { output, stack };
393
- }
394
- /**
395
- * Pre-processes the input to replace circular references with transformer objects
396
- * @param raw - The raw value to process
397
- * @returns The processed value with circular references replaced
398
- * @private
399
- */
400
- replaceCircularReferences(raw) {
401
- if (typeof raw !== 'object' || raw === null)
402
- return raw;
403
- const visiting = new WeakSet();
404
- const pathMap = new WeakMap();
405
- const processValue = (value, path) => {
406
- if (typeof value !== 'object' || value === null)
407
- return value;
408
- if (visiting.has(value)) {
409
- const originalPath = pathMap.get(value) || '';
410
- return {
411
- _transformer: 'circular',
412
- value: originalPath,
413
- path: path
414
- };
415
- }
416
- visiting.add(value);
417
- pathMap.set(value, path);
418
- let result;
419
- if (Array.isArray(value)) {
420
- let hasCircular = false;
421
- const newArray = value.map((item, index) => {
422
- const itemPath = path ? `${path}.${index}` : index.toString();
423
- const processed = processValue(item, itemPath);
424
- if (processed !== item)
425
- hasCircular = true;
426
- return processed;
427
- });
428
- result = hasCircular ? newArray : value;
429
- }
430
- else {
431
- let hasCircular = false;
432
- const newObj = {};
433
- for (const [key, val] of Object.entries(value)) {
434
- const valuePath = path ? `${path}.${key}` : key;
435
- const processed = processValue(val, valuePath);
436
- newObj[key] = processed;
437
- if (processed !== val)
438
- hasCircular = true;
439
- }
440
- result = hasCircular ? newObj : value;
441
- }
442
- visiting.delete(value);
443
- return result;
444
- };
445
- return processValue(raw, '');
446
- }
447
- /**
448
- * Checks if a non-traversable value requires transformers
449
- * @param value - The value to check
450
- * @returns Whether the value requires transformers
451
- * @private
452
- */
453
- requiresTransformers(value) {
454
- if (typeof value === 'bigint')
455
- return true;
456
- if (value instanceof Date)
457
- return true;
458
- if (value instanceof Error)
459
- return true;
460
- if (value instanceof Map)
461
- return true;
462
- if (value instanceof RegExp)
463
- return true;
464
- if (value instanceof Set)
465
- return true;
466
- if (value instanceof URL)
467
- return true;
468
- return false;
469
- }
470
- }
471
- exports.default = RedactorUtils;