@logtape/redaction 0.10.0-dev.164 → 0.10.0-dev.168
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/esm/field.js +24 -7
- package/esm/mod.js +1 -0
- package/esm/pattern.js +84 -0
- package/package.json +3 -5
- package/script/field.js +24 -7
- package/script/mod.js +15 -0
- package/script/pattern.js +88 -0
- package/types/deps/jsr.io/@std/assert/0.222.1/assert.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/assert/0.222.1/assert_exists.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/assert/0.222.1/assert_false.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/assert/0.222.1/assert_is_error.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/assert/0.222.1/assert_match.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/assert/0.222.1/assert_throws.d.ts.map +1 -0
- package/types/field.d.ts +10 -2
- package/types/field.d.ts.map +1 -1
- package/types/mod.d.ts +1 -0
- package/types/mod.d.ts.map +1 -1
- package/types/pattern.d.ts +120 -0
- package/types/pattern.d.ts.map +1 -0
- package/types/pattern.test.d.ts.map +1 -0
package/esm/field.js
CHANGED
|
@@ -52,8 +52,16 @@ export function redactByField(sink, options = DEFAULT_REDACT_FIELDS) {
|
|
|
52
52
|
return wrapped;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* Redacts properties
|
|
56
|
-
*
|
|
55
|
+
* Redacts properties from an object based on specified field patterns.
|
|
56
|
+
*
|
|
57
|
+
* This function creates a shallow copy of the input object and applies
|
|
58
|
+
* redaction rules to its properties. For properties that match the redaction
|
|
59
|
+
* patterns, the function either removes them or transforms their values based
|
|
60
|
+
* on the provided action.
|
|
61
|
+
*
|
|
62
|
+
* The redaction process is recursive and will be applied to nested objects
|
|
63
|
+
* as well, allowing for deep redaction of sensitive data in complex object
|
|
64
|
+
* structures.
|
|
57
65
|
* @param properties The properties to redact.
|
|
58
66
|
* @param options The redaction options.
|
|
59
67
|
* @returns The redacted properties.
|
|
@@ -62,13 +70,22 @@ export function redactByField(sink, options = DEFAULT_REDACT_FIELDS) {
|
|
|
62
70
|
export function redactProperties(properties, options) {
|
|
63
71
|
const copy = { ...properties };
|
|
64
72
|
for (const field in copy) {
|
|
65
|
-
if (
|
|
73
|
+
if (shouldFieldRedacted(field, options.fieldPatterns)) {
|
|
74
|
+
if (options.action == null || options.action === "delete") {
|
|
75
|
+
delete copy[field];
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
copy[field] = options.action(copy[field]);
|
|
79
|
+
}
|
|
66
80
|
continue;
|
|
67
|
-
if (options.action == null || options.action === "delete") {
|
|
68
|
-
delete copy[field];
|
|
69
81
|
}
|
|
70
|
-
|
|
71
|
-
|
|
82
|
+
const value = copy[field];
|
|
83
|
+
// Check if value is a vanilla object:
|
|
84
|
+
if (typeof value === "object" && value !== null &&
|
|
85
|
+
(Object.getPrototypeOf(value) === Object.prototype ||
|
|
86
|
+
Object.getPrototypeOf(value) === null)) {
|
|
87
|
+
// @ts-ignore: value is always Record<string, unknown>
|
|
88
|
+
copy[field] = redactProperties(value, options);
|
|
72
89
|
}
|
|
73
90
|
}
|
|
74
91
|
return copy;
|
package/esm/mod.js
CHANGED
package/esm/pattern.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A redaction pattern for email addresses.
|
|
3
|
+
* @since 0.10.0
|
|
4
|
+
*/
|
|
5
|
+
export const EMAIL_ADDRESS_PATTERN = {
|
|
6
|
+
pattern: /[\p{L}0-9.!#$%&'*+/=?^_`{|}~-]+@[\p{L}0-9](?:[\p{L}0-9-]{0,61}[\p{L}0-9])?(?:\.[\p{L}0-9](?:[\p{L}0-9-]{0,61}[\p{L}0-9])?)+/gu,
|
|
7
|
+
replacement: "REDACTED@EMAIL.ADDRESS",
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* A redaction pattern for credit card numbers (including American Express).
|
|
11
|
+
* @since 0.10.0
|
|
12
|
+
*/
|
|
13
|
+
export const CREDIT_CARD_NUMBER_PATTERN = {
|
|
14
|
+
pattern: /(?:\d{4}-){3}\d{4}|(?:\d{4}-){2}\d{6}/g,
|
|
15
|
+
replacement: "XXXX-XXXX-XXXX-XXXX",
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A redaction pattern for U.S. Social Security numbers.
|
|
19
|
+
* @since 0.10.0
|
|
20
|
+
*/
|
|
21
|
+
export const US_SSN_PATTERN = {
|
|
22
|
+
pattern: /\d{3}-\d{2}-\d{4}/g,
|
|
23
|
+
replacement: "XXX-XX-XXXX",
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* A redaction pattern for South Korean resident registration numbers
|
|
27
|
+
* (住民登錄番號).
|
|
28
|
+
* @since 0.10.0
|
|
29
|
+
*/
|
|
30
|
+
export const KR_RRN_PATTERN = {
|
|
31
|
+
pattern: /\d{6}-\d{7}/g,
|
|
32
|
+
replacement: "XXXXXX-XXXXXXX",
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* A redaction pattern for JSON Web Tokens (JWT).
|
|
36
|
+
* @since 0.10.0
|
|
37
|
+
*/
|
|
38
|
+
export const JWT_PATTERN = {
|
|
39
|
+
pattern: /eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/g,
|
|
40
|
+
replacement: "[JWT REDACTED]",
|
|
41
|
+
};
|
|
42
|
+
export function redactByPattern(formatter, patterns) {
|
|
43
|
+
for (const { pattern } of patterns) {
|
|
44
|
+
if (!pattern.global) {
|
|
45
|
+
throw new TypeError(`Pattern ${pattern} does not have the global flag set.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function replaceString(str) {
|
|
49
|
+
for (const p of patterns) {
|
|
50
|
+
// The following ternary operator may seem strange, but it's for
|
|
51
|
+
// making TypeScript happy:
|
|
52
|
+
str = typeof p.replacement === "string"
|
|
53
|
+
? str.replaceAll(p.pattern, p.replacement)
|
|
54
|
+
: str.replaceAll(p.pattern, p.replacement);
|
|
55
|
+
}
|
|
56
|
+
return str;
|
|
57
|
+
}
|
|
58
|
+
function replaceObject(object) {
|
|
59
|
+
if (typeof object === "string")
|
|
60
|
+
return replaceString(object);
|
|
61
|
+
else if (Array.isArray(object))
|
|
62
|
+
return object.map(replaceObject);
|
|
63
|
+
else if (typeof object === "object" && object !== null) {
|
|
64
|
+
// Check if object is a vanilla object:
|
|
65
|
+
if (Object.getPrototypeOf(object) === Object.prototype ||
|
|
66
|
+
Object.getPrototypeOf(object) === null) {
|
|
67
|
+
const redacted = {};
|
|
68
|
+
for (const key in object) {
|
|
69
|
+
redacted[key] =
|
|
70
|
+
// @ts-ignore: object always has key
|
|
71
|
+
replaceObject(object[key]);
|
|
72
|
+
}
|
|
73
|
+
return redacted;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return object;
|
|
77
|
+
}
|
|
78
|
+
return (record) => {
|
|
79
|
+
const output = formatter(record);
|
|
80
|
+
if (typeof output === "string")
|
|
81
|
+
return replaceString(output);
|
|
82
|
+
return output.map(replaceObject);
|
|
83
|
+
};
|
|
84
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logtape/redaction",
|
|
3
|
-
"version": "0.10.0-dev.
|
|
3
|
+
"version": "0.10.0-dev.168+93601094",
|
|
4
4
|
"description": "Redact sensitive data from log messages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"logging",
|
|
@@ -47,13 +47,11 @@
|
|
|
47
47
|
"funding": [
|
|
48
48
|
"https://github.com/sponsors/dahlia"
|
|
49
49
|
],
|
|
50
|
-
"dependencies": {
|
|
51
|
-
"@logtape/logtape": "^0.10.0-dev.162"
|
|
52
|
-
},
|
|
53
50
|
"devDependencies": {
|
|
54
51
|
"@types/node": "^20.9.0",
|
|
55
52
|
"picocolors": "^1.0.0",
|
|
56
|
-
"@deno/shim-deno": "~0.18.0"
|
|
53
|
+
"@deno/shim-deno": "~0.18.0",
|
|
54
|
+
"@logtape/logtape": "^0.10.0-dev.168"
|
|
57
55
|
},
|
|
58
56
|
"_generatedBy": "dnt@dev"
|
|
59
57
|
}
|
package/script/field.js
CHANGED
|
@@ -58,8 +58,16 @@ function redactByField(sink, options = exports.DEFAULT_REDACT_FIELDS) {
|
|
|
58
58
|
return wrapped;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* Redacts properties
|
|
62
|
-
*
|
|
61
|
+
* Redacts properties from an object based on specified field patterns.
|
|
62
|
+
*
|
|
63
|
+
* This function creates a shallow copy of the input object and applies
|
|
64
|
+
* redaction rules to its properties. For properties that match the redaction
|
|
65
|
+
* patterns, the function either removes them or transforms their values based
|
|
66
|
+
* on the provided action.
|
|
67
|
+
*
|
|
68
|
+
* The redaction process is recursive and will be applied to nested objects
|
|
69
|
+
* as well, allowing for deep redaction of sensitive data in complex object
|
|
70
|
+
* structures.
|
|
63
71
|
* @param properties The properties to redact.
|
|
64
72
|
* @param options The redaction options.
|
|
65
73
|
* @returns The redacted properties.
|
|
@@ -68,13 +76,22 @@ function redactByField(sink, options = exports.DEFAULT_REDACT_FIELDS) {
|
|
|
68
76
|
function redactProperties(properties, options) {
|
|
69
77
|
const copy = { ...properties };
|
|
70
78
|
for (const field in copy) {
|
|
71
|
-
if (
|
|
79
|
+
if (shouldFieldRedacted(field, options.fieldPatterns)) {
|
|
80
|
+
if (options.action == null || options.action === "delete") {
|
|
81
|
+
delete copy[field];
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
copy[field] = options.action(copy[field]);
|
|
85
|
+
}
|
|
72
86
|
continue;
|
|
73
|
-
if (options.action == null || options.action === "delete") {
|
|
74
|
-
delete copy[field];
|
|
75
87
|
}
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
const value = copy[field];
|
|
89
|
+
// Check if value is a vanilla object:
|
|
90
|
+
if (typeof value === "object" && value !== null &&
|
|
91
|
+
(Object.getPrototypeOf(value) === Object.prototype ||
|
|
92
|
+
Object.getPrototypeOf(value) === null)) {
|
|
93
|
+
// @ts-ignore: value is always Record<string, unknown>
|
|
94
|
+
copy[field] = redactProperties(value, options);
|
|
78
95
|
}
|
|
79
96
|
}
|
|
80
97
|
return copy;
|
package/script/mod.js
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.redactByField = exports.DEFAULT_REDACT_FIELDS = void 0;
|
|
4
18
|
var field_js_1 = require("./field.js");
|
|
5
19
|
Object.defineProperty(exports, "DEFAULT_REDACT_FIELDS", { enumerable: true, get: function () { return field_js_1.DEFAULT_REDACT_FIELDS; } });
|
|
6
20
|
Object.defineProperty(exports, "redactByField", { enumerable: true, get: function () { return field_js_1.redactByField; } });
|
|
21
|
+
__exportStar(require("./pattern.js"), exports);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JWT_PATTERN = exports.KR_RRN_PATTERN = exports.US_SSN_PATTERN = exports.CREDIT_CARD_NUMBER_PATTERN = exports.EMAIL_ADDRESS_PATTERN = void 0;
|
|
4
|
+
exports.redactByPattern = redactByPattern;
|
|
5
|
+
/**
|
|
6
|
+
* A redaction pattern for email addresses.
|
|
7
|
+
* @since 0.10.0
|
|
8
|
+
*/
|
|
9
|
+
exports.EMAIL_ADDRESS_PATTERN = {
|
|
10
|
+
pattern: /[\p{L}0-9.!#$%&'*+/=?^_`{|}~-]+@[\p{L}0-9](?:[\p{L}0-9-]{0,61}[\p{L}0-9])?(?:\.[\p{L}0-9](?:[\p{L}0-9-]{0,61}[\p{L}0-9])?)+/gu,
|
|
11
|
+
replacement: "REDACTED@EMAIL.ADDRESS",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* A redaction pattern for credit card numbers (including American Express).
|
|
15
|
+
* @since 0.10.0
|
|
16
|
+
*/
|
|
17
|
+
exports.CREDIT_CARD_NUMBER_PATTERN = {
|
|
18
|
+
pattern: /(?:\d{4}-){3}\d{4}|(?:\d{4}-){2}\d{6}/g,
|
|
19
|
+
replacement: "XXXX-XXXX-XXXX-XXXX",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* A redaction pattern for U.S. Social Security numbers.
|
|
23
|
+
* @since 0.10.0
|
|
24
|
+
*/
|
|
25
|
+
exports.US_SSN_PATTERN = {
|
|
26
|
+
pattern: /\d{3}-\d{2}-\d{4}/g,
|
|
27
|
+
replacement: "XXX-XX-XXXX",
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A redaction pattern for South Korean resident registration numbers
|
|
31
|
+
* (住民登錄番號).
|
|
32
|
+
* @since 0.10.0
|
|
33
|
+
*/
|
|
34
|
+
exports.KR_RRN_PATTERN = {
|
|
35
|
+
pattern: /\d{6}-\d{7}/g,
|
|
36
|
+
replacement: "XXXXXX-XXXXXXX",
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* A redaction pattern for JSON Web Tokens (JWT).
|
|
40
|
+
* @since 0.10.0
|
|
41
|
+
*/
|
|
42
|
+
exports.JWT_PATTERN = {
|
|
43
|
+
pattern: /eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/g,
|
|
44
|
+
replacement: "[JWT REDACTED]",
|
|
45
|
+
};
|
|
46
|
+
function redactByPattern(formatter, patterns) {
|
|
47
|
+
for (const { pattern } of patterns) {
|
|
48
|
+
if (!pattern.global) {
|
|
49
|
+
throw new TypeError(`Pattern ${pattern} does not have the global flag set.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function replaceString(str) {
|
|
53
|
+
for (const p of patterns) {
|
|
54
|
+
// The following ternary operator may seem strange, but it's for
|
|
55
|
+
// making TypeScript happy:
|
|
56
|
+
str = typeof p.replacement === "string"
|
|
57
|
+
? str.replaceAll(p.pattern, p.replacement)
|
|
58
|
+
: str.replaceAll(p.pattern, p.replacement);
|
|
59
|
+
}
|
|
60
|
+
return str;
|
|
61
|
+
}
|
|
62
|
+
function replaceObject(object) {
|
|
63
|
+
if (typeof object === "string")
|
|
64
|
+
return replaceString(object);
|
|
65
|
+
else if (Array.isArray(object))
|
|
66
|
+
return object.map(replaceObject);
|
|
67
|
+
else if (typeof object === "object" && object !== null) {
|
|
68
|
+
// Check if object is a vanilla object:
|
|
69
|
+
if (Object.getPrototypeOf(object) === Object.prototype ||
|
|
70
|
+
Object.getPrototypeOf(object) === null) {
|
|
71
|
+
const redacted = {};
|
|
72
|
+
for (const key in object) {
|
|
73
|
+
redacted[key] =
|
|
74
|
+
// @ts-ignore: object always has key
|
|
75
|
+
replaceObject(object[key]);
|
|
76
|
+
}
|
|
77
|
+
return redacted;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return object;
|
|
81
|
+
}
|
|
82
|
+
return (record) => {
|
|
83
|
+
const output = formatter(record);
|
|
84
|
+
if (typeof output === "string")
|
|
85
|
+
return replaceString(output);
|
|
86
|
+
return output.map(replaceObject);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/0.222.1/assert.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,SAAK,GAAG,OAAO,CAAC,IAAI,CAI5D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert_exists.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/0.222.1/assert_exists.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,CAAC,EACT,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,CAOlC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert_false.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/0.222.1/assert_false.ts"],"names":[],"mappings":"AAIA,uDAAuD;AACvD,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,SAAK,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAI1E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert_is_error.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/0.222.1/assert_is_error.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,EACnD,KAAK,EAAE,OAAO,EAEd,UAAU,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,KAAK,IAAI,CAAC,CAmCpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert_match.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/0.222.1/assert_match.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,QAOb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert_throws.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/0.222.1/assert_throws.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,OAAO,EACjB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;AACX;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,EAClD,EAAE,EAAE,MAAM,OAAO,EAEjB,UAAU,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EACrC,WAAW,CAAC,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,MAAM,GACX,CAAC,CAAC"}
|
package/types/field.d.ts
CHANGED
|
@@ -65,8 +65,16 @@ export interface FieldRedactionOptions {
|
|
|
65
65
|
*/
|
|
66
66
|
export declare function redactByField(sink: Sink | Sink & Disposable | Sink & AsyncDisposable, options?: FieldRedactionOptions | FieldPatterns): Sink | Sink & Disposable | Sink & AsyncDisposable;
|
|
67
67
|
/**
|
|
68
|
-
* Redacts properties
|
|
69
|
-
*
|
|
68
|
+
* Redacts properties from an object based on specified field patterns.
|
|
69
|
+
*
|
|
70
|
+
* This function creates a shallow copy of the input object and applies
|
|
71
|
+
* redaction rules to its properties. For properties that match the redaction
|
|
72
|
+
* patterns, the function either removes them or transforms their values based
|
|
73
|
+
* on the provided action.
|
|
74
|
+
*
|
|
75
|
+
* The redaction process is recursive and will be applied to nested objects
|
|
76
|
+
* as well, allowing for deep redaction of sensitive data in complex object
|
|
77
|
+
* structures.
|
|
70
78
|
* @param properties The properties to redact.
|
|
71
79
|
* @param options The redaction options.
|
|
72
80
|
* @returns The redacted properties.
|
package/types/field.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,EAAE,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAcnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;CAC5D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,GAAG,eAAe,EACvD,OAAO,GAAE,qBAAqB,GAAG,aAAqC,GACrE,IAAI,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,GAAG,eAAe,CAUnD;AAED
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,EAAE,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAcnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;CAC5D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,GAAG,eAAe,EACvD,OAAO,GAAE,qBAAqB,GAAG,aAAqC,GACrE,IAAI,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,GAAG,eAAe,CAUnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,OAAO,EAAE,qBAAqB,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,aAAa,GAC3B,OAAO,CAST"}
|
package/types/mod.d.ts
CHANGED
package/types/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { ConsoleFormatter, TextFormatter } from "@logtape/logtape";
|
|
2
|
+
/**
|
|
3
|
+
* A redaction pattern, which is a pair of regular expression and replacement
|
|
4
|
+
* string or function.
|
|
5
|
+
* @since 0.10.0
|
|
6
|
+
*/
|
|
7
|
+
export interface RedactionPattern {
|
|
8
|
+
/**
|
|
9
|
+
* The regular expression to match against. Note that it must have the
|
|
10
|
+
* `g` (global) flag set, otherwise it will throw a `TypeError`.
|
|
11
|
+
*/
|
|
12
|
+
readonly pattern: RegExp;
|
|
13
|
+
/**
|
|
14
|
+
* The replacement string or function. If the replacement is a function,
|
|
15
|
+
* it will be called with the matched string and any capture groups (the same
|
|
16
|
+
* signature as `String.prototype.replaceAll()`).
|
|
17
|
+
*/
|
|
18
|
+
readonly replacement: string | ((match: string, ...rest: readonly any[]) => string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A redaction pattern for email addresses.
|
|
22
|
+
* @since 0.10.0
|
|
23
|
+
*/
|
|
24
|
+
export declare const EMAIL_ADDRESS_PATTERN: RedactionPattern;
|
|
25
|
+
/**
|
|
26
|
+
* A redaction pattern for credit card numbers (including American Express).
|
|
27
|
+
* @since 0.10.0
|
|
28
|
+
*/
|
|
29
|
+
export declare const CREDIT_CARD_NUMBER_PATTERN: RedactionPattern;
|
|
30
|
+
/**
|
|
31
|
+
* A redaction pattern for U.S. Social Security numbers.
|
|
32
|
+
* @since 0.10.0
|
|
33
|
+
*/
|
|
34
|
+
export declare const US_SSN_PATTERN: RedactionPattern;
|
|
35
|
+
/**
|
|
36
|
+
* A redaction pattern for South Korean resident registration numbers
|
|
37
|
+
* (住民登錄番號).
|
|
38
|
+
* @since 0.10.0
|
|
39
|
+
*/
|
|
40
|
+
export declare const KR_RRN_PATTERN: RedactionPattern;
|
|
41
|
+
/**
|
|
42
|
+
* A redaction pattern for JSON Web Tokens (JWT).
|
|
43
|
+
* @since 0.10.0
|
|
44
|
+
*/
|
|
45
|
+
export declare const JWT_PATTERN: RedactionPattern;
|
|
46
|
+
/**
|
|
47
|
+
* A list of {@link RedactionPattern}s.
|
|
48
|
+
* @since 0.10.0
|
|
49
|
+
*/
|
|
50
|
+
export type RedactionPatterns = readonly RedactionPattern[];
|
|
51
|
+
/**
|
|
52
|
+
* Applies data redaction to a {@link TextFormatter}.
|
|
53
|
+
*
|
|
54
|
+
* Note that there are some built-in redaction patterns:
|
|
55
|
+
*
|
|
56
|
+
* - {@link CREDIT_CARD_NUMBER_PATTERN}
|
|
57
|
+
* - {@link EMAIL_ADDRESS_PATTERN}
|
|
58
|
+
* - {@link JWT_PATTERN}
|
|
59
|
+
* - {@link KR_RRN_PATTERN}
|
|
60
|
+
* - {@link US_SSN_PATTERN}
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* import { getFileSink } from "@logtape/file";
|
|
65
|
+
* import { getAnsiColorFormatter } from "@logtape/logtape";
|
|
66
|
+
* import {
|
|
67
|
+
* CREDIT_CARD_NUMBER_PATTERN,
|
|
68
|
+
* EMAIL_ADDRESS_PATTERN,
|
|
69
|
+
* JWT_PATTERN,
|
|
70
|
+
* redactByPattern,
|
|
71
|
+
* } from "@logtape/redaction";
|
|
72
|
+
*
|
|
73
|
+
* const formatter = redactByPattern(getAnsiConsoleFormatter(), [
|
|
74
|
+
* CREDIT_CARD_NUMBER_PATTERN,
|
|
75
|
+
* EMAIL_ADDRESS_PATTERN,
|
|
76
|
+
* JWT_PATTERN,
|
|
77
|
+
* ]);
|
|
78
|
+
* const sink = getFileSink("my-app.log", { formatter });
|
|
79
|
+
* ```
|
|
80
|
+
* @param formatter The text formatter to apply redaction to.
|
|
81
|
+
* @param patterns The redaction patterns to apply.
|
|
82
|
+
* @returns The redacted text formatter.
|
|
83
|
+
* @since 0.10.0
|
|
84
|
+
*/
|
|
85
|
+
export declare function redactByPattern(formatter: TextFormatter, patterns: RedactionPatterns): TextFormatter;
|
|
86
|
+
/**
|
|
87
|
+
* Applies data redaction to a {@link ConsoleFormatter}.
|
|
88
|
+
*
|
|
89
|
+
* Note that there are some built-in redaction patterns:
|
|
90
|
+
*
|
|
91
|
+
* - {@link CREDIT_CARD_NUMBER_PATTERN}
|
|
92
|
+
* - {@link EMAIL_ADDRESS_PATTERN}
|
|
93
|
+
* - {@link JWT_PATTERN}
|
|
94
|
+
* - {@link KR_RRN_PATTERN}
|
|
95
|
+
* - {@link US_SSN_PATTERN}
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* import { defaultConsoleFormatter, getConsoleSink } from "@logtape/logtape";
|
|
100
|
+
* import {
|
|
101
|
+
* CREDIT_CARD_NUMBER_PATTERN,
|
|
102
|
+
* EMAIL_ADDRESS_PATTERN,
|
|
103
|
+
* JWT_PATTERN,
|
|
104
|
+
* redactByPattern,
|
|
105
|
+
* } from "@logtape/redaction";
|
|
106
|
+
*
|
|
107
|
+
* const formatter = redactByPattern(defaultConsoleFormatter, [
|
|
108
|
+
* CREDIT_CARD_NUMBER_PATTERN,
|
|
109
|
+
* EMAIL_ADDRESS_PATTERN,
|
|
110
|
+
* JWT_PATTERN,
|
|
111
|
+
* ]);
|
|
112
|
+
* const sink = getConsoleSink({ formatter });
|
|
113
|
+
* ```
|
|
114
|
+
* @param formatter The console formatter to apply redaction to.
|
|
115
|
+
* @param patterns The redaction patterns to apply.
|
|
116
|
+
* @returns The redacted console formatter.
|
|
117
|
+
* @since 0.10.0
|
|
118
|
+
*/
|
|
119
|
+
export declare function redactByPattern(formatter: ConsoleFormatter, patterns: RedactionPatterns): ConsoleFormatter;
|
|
120
|
+
//# sourceMappingURL=pattern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../src/pattern.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAEhB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAChB,MAAM,GAEN,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,SAAS,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC;CAC1D;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,gBAInC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,gBAGxC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,gBAG5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,gBAG5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,gBAGzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,gBAAgB,EAAE,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,aAAa,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,iBAAiB,GAC1B,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern.test.d.ts","sourceRoot":"","sources":["../src/pattern.test.ts"],"names":[],"mappings":""}
|