field-redactor 1.1.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +38 -0
- package/CHANGELOG.md +156 -0
- package/README.md +64 -647
- package/dist/configValidator.d.ts +10 -0
- package/dist/configValidator.d.ts.map +1 -0
- package/dist/configValidator.js +94 -0
- package/dist/configValidator.js.map +1 -0
- package/dist/copyOnWriteHelpers.d.ts +20 -0
- package/dist/copyOnWriteHelpers.d.ts.map +1 -0
- package/dist/copyOnWriteHelpers.js +58 -0
- package/dist/copyOnWriteHelpers.js.map +1 -0
- package/dist/customObjectManager.d.ts +13 -7
- package/dist/customObjectManager.d.ts.map +1 -1
- package/dist/customObjectManager.js +30 -29
- package/dist/customObjectManager.js.map +1 -1
- package/dist/dryRun.d.ts +8 -0
- package/dist/dryRun.d.ts.map +1 -0
- package/dist/dryRun.js +75 -0
- package/dist/dryRun.js.map +1 -0
- package/dist/dryRunAttribution.d.ts +8 -0
- package/dist/dryRunAttribution.d.ts.map +1 -0
- package/dist/dryRunAttribution.js +106 -0
- package/dist/dryRunAttribution.js.map +1 -0
- package/dist/fieldRedactor.d.ts +43 -5
- package/dist/fieldRedactor.d.ts.map +1 -1
- package/dist/fieldRedactor.js +124 -23
- package/dist/fieldRedactor.js.map +1 -1
- package/dist/fieldRedactorConfigBuilder.d.ts +49 -0
- package/dist/fieldRedactorConfigBuilder.d.ts.map +1 -0
- package/dist/fieldRedactorConfigBuilder.js +98 -0
- package/dist/fieldRedactorConfigBuilder.js.map +1 -0
- package/dist/fieldRedactorDeps.d.ts +17 -0
- package/dist/fieldRedactorDeps.d.ts.map +1 -0
- package/dist/fieldRedactorDeps.js +41 -0
- package/dist/fieldRedactorDeps.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/jsonWalk.d.ts +11 -0
- package/dist/jsonWalk.d.ts.map +1 -0
- package/dist/jsonWalk.js +86 -0
- package/dist/jsonWalk.js.map +1 -0
- package/dist/objectRedactor.d.ts +9 -34
- package/dist/objectRedactor.d.ts.map +1 -1
- package/dist/objectRedactor.js +11 -271
- package/dist/objectRedactor.js.map +1 -1
- package/dist/objectRedactorCow.d.ts +35 -0
- package/dist/objectRedactorCow.d.ts.map +1 -0
- package/dist/objectRedactorCow.js +300 -0
- package/dist/objectRedactorCow.js.map +1 -0
- package/dist/objectRedactorCustomObject.d.ts +49 -0
- package/dist/objectRedactorCustomObject.d.ts.map +1 -0
- package/dist/objectRedactorCustomObject.js +138 -0
- package/dist/objectRedactorCustomObject.js.map +1 -0
- package/dist/objectRedactorHelpers.d.ts +9 -0
- package/dist/objectRedactorHelpers.d.ts.map +1 -0
- package/dist/objectRedactorHelpers.js +58 -0
- package/dist/objectRedactorHelpers.js.map +1 -0
- package/dist/objectRedactorMutation.d.ts +10 -0
- package/dist/objectRedactorMutation.d.ts.map +1 -0
- package/dist/objectRedactorMutation.js +89 -0
- package/dist/objectRedactorMutation.js.map +1 -0
- package/dist/objectRedactorSync.d.ts +2 -0
- package/dist/objectRedactorSync.d.ts.map +1 -0
- package/dist/objectRedactorSync.js +7 -0
- package/dist/objectRedactorSync.js.map +1 -0
- package/dist/objectRedactorTraversal.d.ts +57 -0
- package/dist/objectRedactorTraversal.d.ts.map +1 -0
- package/dist/objectRedactorTraversal.js +576 -0
- package/dist/objectRedactorTraversal.js.map +1 -0
- package/dist/presets.d.ts +22 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +50 -0
- package/dist/presets.js.map +1 -0
- package/dist/primitiveRedactor.d.ts +13 -8
- package/dist/primitiveRedactor.d.ts.map +1 -1
- package/dist/primitiveRedactor.js +32 -27
- package/dist/primitiveRedactor.js.map +1 -1
- package/dist/redactionRules.d.ts +23 -0
- package/dist/redactionRules.d.ts.map +1 -0
- package/dist/redactionRules.js +76 -0
- package/dist/redactionRules.js.map +1 -0
- package/dist/regexUtils.d.ts +3 -0
- package/dist/regexUtils.d.ts.map +1 -0
- package/dist/regexUtils.js +8 -0
- package/dist/regexUtils.js.map +1 -0
- package/dist/secretManager.d.ts +18 -5
- package/dist/secretManager.d.ts.map +1 -1
- package/dist/secretManager.js +49 -11
- package/dist/secretManager.js.map +1 -1
- package/dist/types.d.ts +110 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +13 -6
- package/dist/types.js.map +1 -1
- package/dist/valuePatternMatcher.d.ts +15 -0
- package/dist/valuePatternMatcher.d.ts.map +1 -0
- package/dist/valuePatternMatcher.js +30 -0
- package/dist/valuePatternMatcher.js.map +1 -0
- package/docs/guides/anti-patterns.md +107 -0
- package/docs/guides/metadata-redaction.md +112 -0
- package/docs/guides/migration-1.2-to-1.5.md +106 -0
- package/docs/guides/secret-key-modes.md +108 -0
- package/docs/guides/value-pattern-redaction.md +58 -0
- package/docs/reference/config.md +135 -0
- package/docs/release-notes/2.0.0.md +19 -0
- package/docs/release-notes/2.1.0.md +17 -0
- package/docs/release-notes/2.2.0.md +16 -0
- package/docs/release-notes/2.3.0.md +17 -0
- package/docs/release-notes/2.3.1.md +17 -0
- package/docs/release-notes/2.4.0.md +30 -0
- package/docs/release-notes/2.5.0.md +33 -0
- package/docs/release-notes/2.5.1.md +17 -0
- package/docs/release-notes/README.md +30 -0
- package/docs/release-notes/v1.0.0.md +17 -0
- package/docs/release-notes/v1.1.0.md +18 -0
- package/docs/release-notes/v1.2.0.md +18 -0
- package/docs/release-notes/v1.2.1.md +16 -0
- package/docs/release-notes/v1.2.2.md +19 -0
- package/docs/release-notes/v1.3.0.md +112 -0
- package/docs/release-notes/v1.5.0.md +88 -0
- package/jest.config.js +4 -1
- package/package.json +3 -3
package/dist/fieldRedactor.d.ts
CHANGED
|
@@ -1,13 +1,39 @@
|
|
|
1
|
-
import { FieldRedactorConfig } from './types';
|
|
1
|
+
import { DryRunResult, FieldRedactorConfig, RedactableInput } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* FieldRedactor is a highly customizable JSON object field redactor. It conditionally redacts fields based on
|
|
4
4
|
* the secrets, deepSecrets, fullSecrets, and custom objects provided in the configuration. Refer to the README.md
|
|
5
5
|
* for more details.
|
|
6
|
+
*
|
|
7
|
+
* Defaults: `ignoreNullOrUndefined` is `true`, `ignoreBooleans` is `false`, `cloneInput` is `true`.
|
|
6
8
|
*/
|
|
7
9
|
export declare class FieldRedactor {
|
|
8
|
-
private deepCopy;
|
|
10
|
+
private readonly deepCopy;
|
|
9
11
|
private readonly objectRedactor;
|
|
12
|
+
private readonly customObjectManager;
|
|
13
|
+
private readonly secretManager;
|
|
14
|
+
private readonly usesAsyncRedactor;
|
|
15
|
+
private readonly cloneInput;
|
|
16
|
+
private readonly valuePatternMatcher;
|
|
17
|
+
/** Non-fatal configuration warnings from the last construction (empty when `strict` threw). */
|
|
18
|
+
readonly configWarnings: readonly string[];
|
|
10
19
|
constructor(config?: FieldRedactorConfig);
|
|
20
|
+
/**
|
|
21
|
+
* Creates a FieldRedactor that requires at least one explicit redaction rule: Shallow (`secretKeys`),
|
|
22
|
+
* Deep (`deepSecretKeys`), Opaque (`fullSecretKeys`), Remove (`deleteSecretKeys`), Schema (`customObjects`),
|
|
23
|
+
* or Value-pattern (`valuePatterns`).
|
|
24
|
+
* Unlike `new FieldRedactor()`, omitting all rules does not default to redacting every value.
|
|
25
|
+
*/
|
|
26
|
+
static createSafe(config: FieldRedactorConfig): FieldRedactor;
|
|
27
|
+
/**
|
|
28
|
+
* Redacts a copy of the input and returns an audit report of affected paths without mutating the original.
|
|
29
|
+
*/
|
|
30
|
+
dryRun<T extends RedactableInput>(value: T): Promise<DryRunResult<T>>;
|
|
31
|
+
/**
|
|
32
|
+
* Synchronous {@link FieldRedactor.dryRun} without per-field Promise overhead.
|
|
33
|
+
*/
|
|
34
|
+
dryRunSync<T extends RedactableInput>(value: T): DryRunResult<T>;
|
|
35
|
+
private emptyDryRunResult;
|
|
36
|
+
private toDryRunResult;
|
|
11
37
|
/**
|
|
12
38
|
* Conditionally redacts fields in the JSON object based on the configuration provided in the constructor and returns the
|
|
13
39
|
* redacted result.
|
|
@@ -15,14 +41,26 @@ export declare class FieldRedactor {
|
|
|
15
41
|
* @param value The JSON value to redact. If primitive it will be resolved as-is.
|
|
16
42
|
* @returns The redacted JSON object.
|
|
17
43
|
*/
|
|
18
|
-
redact(value:
|
|
44
|
+
redact<T extends RedactableInput>(value: T): Promise<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Synchronously redacts fields and returns a copy without per-field Promise overhead.
|
|
47
|
+
* Uses copy-on-write structural sharing by default so only mutated branches are cloned.
|
|
48
|
+
*/
|
|
49
|
+
redactSync<T extends RedactableInput>(value: T): T;
|
|
19
50
|
/**
|
|
20
51
|
* Conditionally redacts fields in the JSON object in place based on the configuration provided in the constructor.
|
|
21
52
|
* If the value is a primitive, undefined, or date, returns the value as-is.
|
|
22
53
|
* @param value The JSON value to redact in place. If primitive it will be resolved as-is.
|
|
23
|
-
* @returns The redacted JSON object.
|
|
24
54
|
*/
|
|
25
|
-
redactInPlace(value:
|
|
55
|
+
redactInPlace<T extends RedactableInput>(value: T): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Synchronously redacts fields in the JSON object in place without per-field Promise overhead.
|
|
58
|
+
* Requires a `syncRedactor` or the default redactor; throws when only an async `redactor` is configured.
|
|
59
|
+
*/
|
|
60
|
+
redactInPlaceSync<T extends RedactableInput>(value: T): void;
|
|
61
|
+
private runTraversableRedactionSync;
|
|
62
|
+
private runTraversableRedactionAsync;
|
|
63
|
+
private toFieldRedactorError;
|
|
26
64
|
private isPrimitiveOrUndefined;
|
|
27
65
|
}
|
|
28
66
|
//# sourceMappingURL=fieldRedactor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldRedactor.d.ts","sourceRoot":"","sources":["../src/fieldRedactor.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"fieldRedactor.d.ts","sourceRoot":"","sources":["../src/fieldRedactor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,mBAAmB,EAInB,eAAe,EAEhB,MAAM,SAAS,CAAC;AASjB;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAmE;IAEvG,+FAA+F;IAC/F,SAAgB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;gBAEtC,MAAM,CAAC,EAAE,mBAAmB;IAgBxC;;;;;OAKG;WACW,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa;IAUpE;;OAEG;IACU,MAAM,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IASlF;;OAEG;IACI,UAAU,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;IASvE,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,cAAc;IAatB;;;;;;OAMG;IACU,MAAM,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAmBpE;;;OAGG;IACI,UAAU,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAazD;;;;OAIG;IACU,aAAa,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9E;;;OAGG;IACI,iBAAiB,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAQnE,OAAO,CAAC,2BAA2B;YAYrB,4BAA4B;IAe1C,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,sBAAsB;CAG/B"}
|
package/dist/fieldRedactor.js
CHANGED
|
@@ -14,34 +14,75 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.FieldRedactor = void 0;
|
|
16
16
|
const rfdc_1 = __importDefault(require("rfdc"));
|
|
17
|
-
const objectRedactor_1 = require("./objectRedactor");
|
|
18
|
-
const primitiveRedactor_1 = require("./primitiveRedactor");
|
|
19
|
-
const secretManager_1 = require("./secretManager");
|
|
20
|
-
const customObjectManager_1 = require("./customObjectManager");
|
|
21
17
|
const errors_1 = require("./errors");
|
|
18
|
+
const configValidator_1 = require("./configValidator");
|
|
19
|
+
const dryRun_1 = require("./dryRun");
|
|
20
|
+
const fieldRedactorDeps_1 = require("./fieldRedactorDeps");
|
|
22
21
|
/**
|
|
23
22
|
* FieldRedactor is a highly customizable JSON object field redactor. It conditionally redacts fields based on
|
|
24
23
|
* the secrets, deepSecrets, fullSecrets, and custom objects provided in the configuration. Refer to the README.md
|
|
25
24
|
* for more details.
|
|
25
|
+
*
|
|
26
|
+
* Defaults: `ignoreNullOrUndefined` is `true`, `ignoreBooleans` is `false`, `cloneInput` is `true`.
|
|
26
27
|
*/
|
|
27
28
|
class FieldRedactor {
|
|
28
29
|
constructor(config) {
|
|
30
|
+
var _a;
|
|
29
31
|
this.deepCopy = (0, rfdc_1.default)({ proto: true, circles: true });
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
this.configWarnings = (0, configValidator_1.validateFieldRedactorConfig)(config);
|
|
33
|
+
for (const warning of this.configWarnings) {
|
|
34
|
+
(_a = config === null || config === void 0 ? void 0 : config.onConfigWarning) === null || _a === void 0 ? void 0 : _a.call(config, warning);
|
|
35
|
+
}
|
|
36
|
+
const deps = (0, fieldRedactorDeps_1.buildFieldRedactorDeps)(config);
|
|
37
|
+
this.usesAsyncRedactor = deps.usesAsyncRedactor;
|
|
38
|
+
this.cloneInput = deps.cloneInput;
|
|
39
|
+
this.secretManager = deps.secretManager;
|
|
40
|
+
this.valuePatternMatcher = deps.valuePatternMatcher;
|
|
41
|
+
this.customObjectManager = deps.customObjectManager;
|
|
42
|
+
this.objectRedactor = deps.objectRedactor;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a FieldRedactor that requires at least one explicit redaction rule: Shallow (`secretKeys`),
|
|
46
|
+
* Deep (`deepSecretKeys`), Opaque (`fullSecretKeys`), Remove (`deleteSecretKeys`), Schema (`customObjects`),
|
|
47
|
+
* or Value-pattern (`valuePatterns`).
|
|
48
|
+
* Unlike `new FieldRedactor()`, omitting all rules does not default to redacting every value.
|
|
49
|
+
*/
|
|
50
|
+
static createSafe(config) {
|
|
51
|
+
if (!(0, configValidator_1.hasExplicitRedactionRules)(config)) {
|
|
52
|
+
throw new errors_1.FieldRedactorConfigurationError('FieldRedactor.createSafe() requires at least one non-empty secretKeys, deepSecretKeys, fullSecretKeys, deleteSecretKeys, customObjects, or valuePatterns entry. Without explicit rules, new FieldRedactor() redacts all values by default.');
|
|
53
|
+
}
|
|
54
|
+
return new FieldRedactor(config);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Redacts a copy of the input and returns an audit report of affected paths without mutating the original.
|
|
58
|
+
*/
|
|
59
|
+
dryRun(value) {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
if (this.isPrimitiveOrUndefined(value)) {
|
|
62
|
+
return this.emptyDryRunResult(value);
|
|
63
|
+
}
|
|
64
|
+
const snapshot = this.deepCopy(value);
|
|
65
|
+
return this.toDryRunResult(snapshot, yield this.redact(value));
|
|
42
66
|
});
|
|
43
|
-
|
|
44
|
-
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Synchronous {@link FieldRedactor.dryRun} without per-field Promise overhead.
|
|
70
|
+
*/
|
|
71
|
+
dryRunSync(value) {
|
|
72
|
+
if (this.isPrimitiveOrUndefined(value)) {
|
|
73
|
+
return this.emptyDryRunResult(value);
|
|
74
|
+
}
|
|
75
|
+
const snapshot = this.deepCopy(value);
|
|
76
|
+
return this.toDryRunResult(snapshot, this.redactSync(value));
|
|
77
|
+
}
|
|
78
|
+
emptyDryRunResult(value) {
|
|
79
|
+
return { result: value, report: dryRun_1.EMPTY_DRY_RUN_REPORT };
|
|
80
|
+
}
|
|
81
|
+
toDryRunResult(snapshot, result) {
|
|
82
|
+
return {
|
|
83
|
+
result,
|
|
84
|
+
report: (0, dryRun_1.buildDryRunReport)(snapshot, result, this.customObjectManager, this.secretManager, this.valuePatternMatcher)
|
|
85
|
+
};
|
|
45
86
|
}
|
|
46
87
|
/**
|
|
47
88
|
* Conditionally redacts fields in the JSON object based on the configuration provided in the constructor and returns the
|
|
@@ -52,29 +93,89 @@ class FieldRedactor {
|
|
|
52
93
|
*/
|
|
53
94
|
redact(value) {
|
|
54
95
|
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
if (this.isPrimitiveOrUndefined(value)) {
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
if (!this.cloneInput) {
|
|
100
|
+
yield this.redactInPlace(value);
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
if (!this.usesAsyncRedactor) {
|
|
104
|
+
return Promise.resolve(this.redactSync(value));
|
|
105
|
+
}
|
|
55
106
|
const copy = this.deepCopy(value);
|
|
56
|
-
|
|
107
|
+
yield this.redactInPlace(copy);
|
|
108
|
+
return copy;
|
|
57
109
|
});
|
|
58
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Synchronously redacts fields and returns a copy without per-field Promise overhead.
|
|
113
|
+
* Uses copy-on-write structural sharing by default so only mutated branches are cloned.
|
|
114
|
+
*/
|
|
115
|
+
redactSync(value) {
|
|
116
|
+
if (this.isPrimitiveOrUndefined(value)) {
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
if (!this.cloneInput) {
|
|
120
|
+
this.redactInPlaceSync(value);
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
123
|
+
return this.objectRedactor.redactCopyOnWrite(value);
|
|
124
|
+
}
|
|
59
125
|
/**
|
|
60
126
|
* Conditionally redacts fields in the JSON object in place based on the configuration provided in the constructor.
|
|
61
127
|
* If the value is a primitive, undefined, or date, returns the value as-is.
|
|
62
128
|
* @param value The JSON value to redact in place. If primitive it will be resolved as-is.
|
|
63
|
-
* @returns The redacted JSON object.
|
|
64
129
|
*/
|
|
65
130
|
redactInPlace(value) {
|
|
131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
+
if (!this.usesAsyncRedactor) {
|
|
133
|
+
this.redactInPlaceSync(value);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
yield this.runTraversableRedactionAsync(value, () => __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
yield this.objectRedactor.redactInPlace(value);
|
|
138
|
+
}));
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Synchronously redacts fields in the JSON object in place without per-field Promise overhead.
|
|
143
|
+
* Requires a `syncRedactor` or the default redactor; throws when only an async `redactor` is configured.
|
|
144
|
+
*/
|
|
145
|
+
redactInPlaceSync(value) {
|
|
146
|
+
if (this.usesAsyncRedactor) {
|
|
147
|
+
throw new errors_1.FieldRedactorError('redactInPlaceSync requires syncRedactor configuration or the default redactor');
|
|
148
|
+
}
|
|
149
|
+
this.runTraversableRedactionSync(value, () => this.objectRedactor.redactInPlaceSync(value));
|
|
150
|
+
}
|
|
151
|
+
runTraversableRedactionSync(value, redact) {
|
|
152
|
+
if (this.isPrimitiveOrUndefined(value)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
redact();
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
throw this.toFieldRedactorError(e);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
runTraversableRedactionAsync(value, redact) {
|
|
66
163
|
return __awaiter(this, void 0, void 0, function* () {
|
|
67
164
|
if (this.isPrimitiveOrUndefined(value)) {
|
|
68
|
-
return
|
|
165
|
+
return;
|
|
69
166
|
}
|
|
70
167
|
try {
|
|
71
|
-
|
|
168
|
+
yield redact();
|
|
72
169
|
}
|
|
73
170
|
catch (e) {
|
|
74
|
-
throw
|
|
171
|
+
throw this.toFieldRedactorError(e);
|
|
75
172
|
}
|
|
76
173
|
});
|
|
77
174
|
}
|
|
175
|
+
toFieldRedactorError(error) {
|
|
176
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
177
|
+
return new errors_1.FieldRedactorError(message);
|
|
178
|
+
}
|
|
78
179
|
isPrimitiveOrUndefined(value) {
|
|
79
180
|
return !value || typeof value !== 'object' || value instanceof Date;
|
|
80
181
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldRedactor.js","sourceRoot":"","sources":["../src/fieldRedactor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gDAAwB;
|
|
1
|
+
{"version":3,"file":"fieldRedactor.js","sourceRoot":"","sources":["../src/fieldRedactor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { FieldRedactor } from './fieldRedactor';
|
|
2
|
+
import { CustomObject, FieldRedactorConfig, Redactor, SyncRedactor } from './types';
|
|
3
|
+
export type SchemaOptions = {
|
|
4
|
+
/** Optional label surfaced in {@link FieldRedactor.dryRun} `matchedSchemas` reports. */
|
|
5
|
+
name?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Fluent builder for {@link FieldRedactorConfig} using doc labels (Shallow, Deep, Opaque, Remove, Schema).
|
|
9
|
+
*/
|
|
10
|
+
export declare class FieldRedactorConfigBuilder {
|
|
11
|
+
private config;
|
|
12
|
+
private schemas;
|
|
13
|
+
static create(): FieldRedactorConfigBuilder;
|
|
14
|
+
/** Shallow — redact matching keys' scalar values (`secretKeys`). */
|
|
15
|
+
shallow(...patterns: RegExp[]): this;
|
|
16
|
+
/** Deep — redact matching keys and descendants (`deepSecretKeys`). */
|
|
17
|
+
deep(...patterns: RegExp[]): this;
|
|
18
|
+
/** Opaque — stringify entire values at matching keys (`fullSecretKeys`). */
|
|
19
|
+
opaque(...patterns: RegExp[]): this;
|
|
20
|
+
/** Remove — delete matching keys from output (`deleteSecretKeys`). */
|
|
21
|
+
remove(...patterns: RegExp[]): this;
|
|
22
|
+
/** Alias for {@link FieldRedactorConfigBuilder.remove}. */
|
|
23
|
+
delete(...patterns: RegExp[]): this;
|
|
24
|
+
/** Register an object schema (`customObjects`). */
|
|
25
|
+
schema(customObject: CustomObject, options?: SchemaOptions): this;
|
|
26
|
+
/**
|
|
27
|
+
* Value-pattern — redact scalar fields whose string form matches a pattern, regardless of key name (`valuePatterns`).
|
|
28
|
+
* Lowest precedence; opt-in defense in depth beyond key-name rules.
|
|
29
|
+
*/
|
|
30
|
+
valuePattern(...patterns: RegExp[]): this;
|
|
31
|
+
/**
|
|
32
|
+
* Merge a {@link presets} return value (or any partial config) into the builder.
|
|
33
|
+
* Regex arrays and schemas accumulate; scalar options apply only when not already set.
|
|
34
|
+
*/
|
|
35
|
+
usePreset(preset: Partial<FieldRedactorConfig>): this;
|
|
36
|
+
redactor(fn: Redactor): this;
|
|
37
|
+
syncRedactor(fn: SyncRedactor): this;
|
|
38
|
+
ignoreBooleans(value: boolean): this;
|
|
39
|
+
ignoreNullOrUndefined(value: boolean): this;
|
|
40
|
+
cloneInput(value: boolean): this;
|
|
41
|
+
strict(value?: boolean): this;
|
|
42
|
+
onConfigWarning(handler: (message: string) => void): this;
|
|
43
|
+
build(): FieldRedactorConfig;
|
|
44
|
+
buildRedactor(): FieldRedactor;
|
|
45
|
+
buildSafeRedactor(): FieldRedactor;
|
|
46
|
+
private appendRegex;
|
|
47
|
+
private set;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=fieldRedactorConfigBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldRedactorConfigBuilder.d.ts","sourceRoot":"","sources":["../src/fieldRedactorConfigBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAShD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEpF,MAAM,MAAM,aAAa,GAAG;IAC1B,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,OAAO,CAA0B;IAEzC,MAAM,CAAC,MAAM,IAAI,0BAA0B;IAI3C,oEAAoE;IACpE,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpC,sEAAsE;IACtE,IAAI,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAIjC,4EAA4E;IAC5E,MAAM,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAInC,sEAAsE;IACtE,MAAM,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAInC,2DAA2D;IAC3D,MAAM,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAInC,mDAAmD;IACnD,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;IAKjE;;;OAGG;IACH,YAAY,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAKzC;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAKrD,QAAQ,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAI5B,YAAY,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI;IAIpC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAIpC,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI3C,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAIhC,MAAM,CAAC,KAAK,UAAO,GAAG,IAAI;IAI1B,eAAe,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIzD,KAAK,IAAI,mBAAmB;IAI5B,aAAa,IAAI,aAAa;IAI9B,iBAAiB,IAAI,aAAa;IAIlC,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,GAAG;CAIZ"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FieldRedactorConfigBuilder = void 0;
|
|
4
|
+
const fieldRedactor_1 = require("./fieldRedactor");
|
|
5
|
+
const redactionRules_1 = require("./redactionRules");
|
|
6
|
+
/**
|
|
7
|
+
* Fluent builder for {@link FieldRedactorConfig} using doc labels (Shallow, Deep, Opaque, Remove, Schema).
|
|
8
|
+
*/
|
|
9
|
+
class FieldRedactorConfigBuilder {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.config = {};
|
|
12
|
+
this.schemas = [];
|
|
13
|
+
}
|
|
14
|
+
static create() {
|
|
15
|
+
return new FieldRedactorConfigBuilder();
|
|
16
|
+
}
|
|
17
|
+
/** Shallow — redact matching keys' scalar values (`secretKeys`). */
|
|
18
|
+
shallow(...patterns) {
|
|
19
|
+
return this.appendRegex('secretKeys', patterns);
|
|
20
|
+
}
|
|
21
|
+
/** Deep — redact matching keys and descendants (`deepSecretKeys`). */
|
|
22
|
+
deep(...patterns) {
|
|
23
|
+
return this.appendRegex('deepSecretKeys', patterns);
|
|
24
|
+
}
|
|
25
|
+
/** Opaque — stringify entire values at matching keys (`fullSecretKeys`). */
|
|
26
|
+
opaque(...patterns) {
|
|
27
|
+
return this.appendRegex('fullSecretKeys', patterns);
|
|
28
|
+
}
|
|
29
|
+
/** Remove — delete matching keys from output (`deleteSecretKeys`). */
|
|
30
|
+
remove(...patterns) {
|
|
31
|
+
return this.appendRegex('deleteSecretKeys', patterns);
|
|
32
|
+
}
|
|
33
|
+
/** Alias for {@link FieldRedactorConfigBuilder.remove}. */
|
|
34
|
+
delete(...patterns) {
|
|
35
|
+
return this.remove(...patterns);
|
|
36
|
+
}
|
|
37
|
+
/** Register an object schema (`customObjects`). */
|
|
38
|
+
schema(customObject, options) {
|
|
39
|
+
this.schemas.push({ object: customObject, name: options === null || options === void 0 ? void 0 : options.name });
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Value-pattern — redact scalar fields whose string form matches a pattern, regardless of key name (`valuePatterns`).
|
|
44
|
+
* Lowest precedence; opt-in defense in depth beyond key-name rules.
|
|
45
|
+
*/
|
|
46
|
+
valuePattern(...patterns) {
|
|
47
|
+
(0, redactionRules_1.appendRegExpArray)(this.config, 'valuePatterns', patterns);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Merge a {@link presets} return value (or any partial config) into the builder.
|
|
52
|
+
* Regex arrays and schemas accumulate; scalar options apply only when not already set.
|
|
53
|
+
*/
|
|
54
|
+
usePreset(preset) {
|
|
55
|
+
(0, redactionRules_1.mergePartialConfig)(this.config, this.schemas, preset);
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
redactor(fn) {
|
|
59
|
+
return this.set('redactor', fn);
|
|
60
|
+
}
|
|
61
|
+
syncRedactor(fn) {
|
|
62
|
+
return this.set('syncRedactor', fn);
|
|
63
|
+
}
|
|
64
|
+
ignoreBooleans(value) {
|
|
65
|
+
return this.set('ignoreBooleans', value);
|
|
66
|
+
}
|
|
67
|
+
ignoreNullOrUndefined(value) {
|
|
68
|
+
return this.set('ignoreNullOrUndefined', value);
|
|
69
|
+
}
|
|
70
|
+
cloneInput(value) {
|
|
71
|
+
return this.set('cloneInput', value);
|
|
72
|
+
}
|
|
73
|
+
strict(value = true) {
|
|
74
|
+
return this.set('strict', value);
|
|
75
|
+
}
|
|
76
|
+
onConfigWarning(handler) {
|
|
77
|
+
return this.set('onConfigWarning', handler);
|
|
78
|
+
}
|
|
79
|
+
build() {
|
|
80
|
+
return Object.assign(Object.assign({}, this.config), (0, redactionRules_1.finalizeRegisteredSchemas)(this.schemas));
|
|
81
|
+
}
|
|
82
|
+
buildRedactor() {
|
|
83
|
+
return new fieldRedactor_1.FieldRedactor(this.build());
|
|
84
|
+
}
|
|
85
|
+
buildSafeRedactor() {
|
|
86
|
+
return fieldRedactor_1.FieldRedactor.createSafe(this.build());
|
|
87
|
+
}
|
|
88
|
+
appendRegex(field, patterns) {
|
|
89
|
+
(0, redactionRules_1.appendRegexToConfig)(this.config, field, patterns);
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
set(key, value) {
|
|
93
|
+
this.config[key] = value;
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.FieldRedactorConfigBuilder = FieldRedactorConfigBuilder;
|
|
98
|
+
//# sourceMappingURL=fieldRedactorConfigBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldRedactorConfigBuilder.js","sourceRoot":"","sources":["../src/fieldRedactorConfigBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CustomObjectManager } from './customObjectManager';
|
|
2
|
+
import { ObjectRedactor } from './objectRedactor';
|
|
3
|
+
import { PrimitiveRedactor } from './primitiveRedactor';
|
|
4
|
+
import { SecretManager } from './secretManager';
|
|
5
|
+
import { FieldRedactorConfig } from './types';
|
|
6
|
+
import { ValuePatternMatcher } from './valuePatternMatcher';
|
|
7
|
+
export type FieldRedactorDeps = {
|
|
8
|
+
primitiveRedactor: PrimitiveRedactor;
|
|
9
|
+
secretManager: SecretManager;
|
|
10
|
+
valuePatternMatcher: ValuePatternMatcher;
|
|
11
|
+
customObjectManager: CustomObjectManager;
|
|
12
|
+
objectRedactor: ObjectRedactor;
|
|
13
|
+
usesAsyncRedactor: boolean;
|
|
14
|
+
cloneInput: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare const buildFieldRedactorDeps: (config?: FieldRedactorConfig) => FieldRedactorDeps;
|
|
17
|
+
//# sourceMappingURL=fieldRedactorDeps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldRedactorDeps.d.ts","sourceRoot":"","sources":["../src/fieldRedactorDeps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAA+B,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,aAAa,EAAE,aAAa,CAAC;IAC7B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,sBAAsB,YAAa,mBAAmB,KAAG,iBA+CrE,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFieldRedactorDeps = void 0;
|
|
4
|
+
const customObjectManager_1 = require("./customObjectManager");
|
|
5
|
+
const objectRedactor_1 = require("./objectRedactor");
|
|
6
|
+
const primitiveRedactor_1 = require("./primitiveRedactor");
|
|
7
|
+
const redactionRules_1 = require("./redactionRules");
|
|
8
|
+
const secretManager_1 = require("./secretManager");
|
|
9
|
+
const valuePatternMatcher_1 = require("./valuePatternMatcher");
|
|
10
|
+
const buildFieldRedactorDeps = (config) => {
|
|
11
|
+
const { redactor, syncRedactor, deepSecretKeys, fullSecretKeys, deleteSecretKeys, customObjects, valuePatterns } = config !== null && config !== void 0 ? config : {};
|
|
12
|
+
const ignoreNullOrUndefined = typeof (config === null || config === void 0 ? void 0 : config.ignoreNullOrUndefined) === 'boolean' ? config.ignoreNullOrUndefined : true;
|
|
13
|
+
const ignoreBooleans = typeof (config === null || config === void 0 ? void 0 : config.ignoreBooleans) === 'boolean' ? config.ignoreBooleans : false;
|
|
14
|
+
const cloneInput = (config === null || config === void 0 ? void 0 : config.cloneInput) !== false;
|
|
15
|
+
const primitiveRedactor = new primitiveRedactor_1.PrimitiveRedactor({
|
|
16
|
+
ignoreBooleans,
|
|
17
|
+
ignoreNullOrUndefined,
|
|
18
|
+
redactor,
|
|
19
|
+
syncRedactor
|
|
20
|
+
});
|
|
21
|
+
const secretManager = new secretManager_1.SecretManager({
|
|
22
|
+
secretKeys: (0, redactionRules_1.resolveSecretKeys)(config),
|
|
23
|
+
deepSecretKeys,
|
|
24
|
+
fullSecretKeys,
|
|
25
|
+
deleteSecretKeys
|
|
26
|
+
});
|
|
27
|
+
const valuePatternMatcher = (valuePatterns === null || valuePatterns === void 0 ? void 0 : valuePatterns.length) ? new valuePatternMatcher_1.ValuePatternMatcher(valuePatterns) : valuePatternMatcher_1.EMPTY_VALUE_PATTERN_MATCHER;
|
|
28
|
+
const customObjectManager = new customObjectManager_1.CustomObjectManager(customObjects, config === null || config === void 0 ? void 0 : config.schemaNames);
|
|
29
|
+
const objectRedactor = new objectRedactor_1.ObjectRedactor(primitiveRedactor, secretManager, customObjectManager, valuePatternMatcher);
|
|
30
|
+
return {
|
|
31
|
+
primitiveRedactor,
|
|
32
|
+
secretManager,
|
|
33
|
+
valuePatternMatcher,
|
|
34
|
+
customObjectManager,
|
|
35
|
+
objectRedactor,
|
|
36
|
+
usesAsyncRedactor: primitiveRedactor.usesAsyncRedactor(),
|
|
37
|
+
cloneInput
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
exports.buildFieldRedactorDeps = buildFieldRedactorDeps;
|
|
41
|
+
//# sourceMappingURL=fieldRedactorDeps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldRedactorDeps.js","sourceRoot":"","sources":["../src/fieldRedactorDeps.ts"],"names":[],"mappings":";;;AAAA,+DAA4D;AAC5D,qDAAkD;AAClD,2DAAwD;AACxD,qDAAqD;AACrD,mDAAgD;AAEhD,+DAAyF;AAYlF,MAAM,sBAAsB,GAAG,CAAC,MAA4B,EAAqB,EAAE;IACxF,MAAM,EACJ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACd,GAAG,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC;IAEjB,MAAM,qBAAqB,GACzB,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,qBAAqB,CAAA,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3F,MAAM,cAAc,GAAG,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,CAAA,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC;IACnG,MAAM,UAAU,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,MAAK,KAAK,CAAC;IAEhD,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,CAAC;QAC9C,cAAc;QACd,qBAAqB;QACrB,QAAQ;QACR,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,IAAI,6BAAa,CAAC;QACtC,UAAU,EAAE,IAAA,kCAAiB,EAAC,MAAM,CAAC;QACrC,cAAc;QACd,cAAc;QACd,gBAAgB;KACjB,CAAC,CAAC;IACH,MAAM,mBAAmB,GAAG,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,EAAC,CAAC,CAAC,IAAI,yCAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,iDAA2B,CAAC;IACzH,MAAM,mBAAmB,GAAG,IAAI,yCAAmB,CAAC,aAAa,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,CAAC,CAAC;IACxF,MAAM,cAAc,GAAG,IAAI,+BAAc,CACvC,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,CACpB,CAAC;IAEF,OAAO;QACL,iBAAiB;QACjB,aAAa;QACb,mBAAmB;QACnB,mBAAmB;QACnB,cAAc;QACd,iBAAiB,EAAE,iBAAiB,CAAC,iBAAiB,EAAE;QACxD,UAAU;KACX,CAAC;AACJ,CAAC,CAAC;AA/CW,QAAA,sBAAsB,0BA+CjC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { FieldRedactor } from './fieldRedactor';
|
|
2
|
-
export { CustomObjectMatchType, Redactor, FieldRedactorConfig, CustomObject } from './types';
|
|
2
|
+
export { CustomObjectMatchType, Redactor, FieldRedactorConfig, CustomObject, DryRunReport, DryRunResult, DryRunPathRule, MatchedSchemaReport, RedactionRuleLabel, JsonArray, JsonFunction, JsonLeafValue, JsonObject, JsonPrimitive, JsonValue, RedactableInput, RedactablePrimitive, RedactedPrimitive, RedactorInput, SecretSpecifierValue, SyncRedactor, TraversableJson, isJsonObject } from './types';
|
|
3
|
+
export { FieldRedactorError, FieldRedactorConfigurationError } from './errors';
|
|
4
|
+
export { validateFieldRedactorConfig, hasExplicitRedactionRules } from './configValidator';
|
|
5
|
+
export { EMPTY_DRY_RUN_REPORT } from './dryRun';
|
|
6
|
+
export { presets } from './presets';
|
|
7
|
+
export { FieldRedactorConfigBuilder } from './fieldRedactorConfigBuilder';
|
|
8
|
+
export type { SchemaOptions } from './fieldRedactorConfigBuilder';
|
|
3
9
|
export { FieldRedactor };
|
|
4
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,qBAAqB,EACrB,QAAQ,EACR,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FieldRedactor = exports.CustomObjectMatchType = void 0;
|
|
3
|
+
exports.FieldRedactor = exports.FieldRedactorConfigBuilder = exports.presets = exports.EMPTY_DRY_RUN_REPORT = exports.hasExplicitRedactionRules = exports.validateFieldRedactorConfig = exports.FieldRedactorConfigurationError = exports.FieldRedactorError = exports.isJsonObject = exports.CustomObjectMatchType = void 0;
|
|
4
4
|
const fieldRedactor_1 = require("./fieldRedactor");
|
|
5
5
|
Object.defineProperty(exports, "FieldRedactor", { enumerable: true, get: function () { return fieldRedactor_1.FieldRedactor; } });
|
|
6
6
|
var types_1 = require("./types");
|
|
7
7
|
Object.defineProperty(exports, "CustomObjectMatchType", { enumerable: true, get: function () { return types_1.CustomObjectMatchType; } });
|
|
8
|
+
Object.defineProperty(exports, "isJsonObject", { enumerable: true, get: function () { return types_1.isJsonObject; } });
|
|
9
|
+
var errors_1 = require("./errors");
|
|
10
|
+
Object.defineProperty(exports, "FieldRedactorError", { enumerable: true, get: function () { return errors_1.FieldRedactorError; } });
|
|
11
|
+
Object.defineProperty(exports, "FieldRedactorConfigurationError", { enumerable: true, get: function () { return errors_1.FieldRedactorConfigurationError; } });
|
|
12
|
+
var configValidator_1 = require("./configValidator");
|
|
13
|
+
Object.defineProperty(exports, "validateFieldRedactorConfig", { enumerable: true, get: function () { return configValidator_1.validateFieldRedactorConfig; } });
|
|
14
|
+
Object.defineProperty(exports, "hasExplicitRedactionRules", { enumerable: true, get: function () { return configValidator_1.hasExplicitRedactionRules; } });
|
|
15
|
+
var dryRun_1 = require("./dryRun");
|
|
16
|
+
Object.defineProperty(exports, "EMPTY_DRY_RUN_REPORT", { enumerable: true, get: function () { return dryRun_1.EMPTY_DRY_RUN_REPORT; } });
|
|
17
|
+
var presets_1 = require("./presets");
|
|
18
|
+
Object.defineProperty(exports, "presets", { enumerable: true, get: function () { return presets_1.presets; } });
|
|
19
|
+
var fieldRedactorConfigBuilder_1 = require("./fieldRedactorConfigBuilder");
|
|
20
|
+
Object.defineProperty(exports, "FieldRedactorConfigBuilder", { enumerable: true, get: function () { return fieldRedactorConfigBuilder_1.FieldRedactorConfigBuilder; } });
|
|
8
21
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAAgD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAAgD;AAgCvC,8FAhCA,6BAAa,OAgCA;AA/BtB,iCAwBiB;AAvBf,8GAAA,qBAAqB,OAAA;AAsBrB,qGAAA,YAAY,OAAA;AAEd,mCAA+E;AAAtE,4GAAA,kBAAkB,OAAA;AAAE,yHAAA,+BAA+B,OAAA;AAC5D,qDAA2F;AAAlF,8HAAA,2BAA2B,OAAA;AAAE,4HAAA,yBAAyB,OAAA;AAC/D,mCAAgD;AAAvC,8GAAA,oBAAoB,OAAA;AAC7B,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,2EAA0E;AAAjE,wIAAA,0BAA0B,OAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { JsonArray, JsonObject, JsonValue } from './types';
|
|
2
|
+
export declare const parseJsonPath: (path: string) => Array<string | number>;
|
|
3
|
+
export declare const getJsonValueAtPath: (value: JsonValue | undefined, segments: Array<string | number>) => JsonValue | undefined;
|
|
4
|
+
export declare const getParentContext: (value: JsonValue | undefined, segments: Array<string | number>) => {
|
|
5
|
+
parent: JsonObject | JsonArray | undefined;
|
|
6
|
+
leaf: string | number | undefined;
|
|
7
|
+
};
|
|
8
|
+
export declare const joinPath: (base: string, segment: string | number) => string;
|
|
9
|
+
export declare const isTraversableJson: (value: JsonValue | undefined) => value is JsonObject | JsonValue[];
|
|
10
|
+
export declare const walkTraversableJson: (value: JsonValue | undefined, path: string, visit: (value: JsonValue, path: string) => void) => void;
|
|
11
|
+
//# sourceMappingURL=jsonWalk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonWalk.d.ts","sourceRoot":"","sources":["../src/jsonWalk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzE,eAAO,MAAM,aAAa,SAAU,MAAM,KAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAuCjE,CAAC;AAEF,eAAO,MAAM,kBAAkB,UAAW,SAAS,GAAG,SAAS,YAAY,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAG,SAAS,GAAG,SAsB/G,CAAC;AAEF,eAAO,MAAM,gBAAgB,UACpB,SAAS,GAAG,SAAS,YAClB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAC/B;IAAE,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAUjF,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAAW,MAAM,GAAG,MAAM,KAAG,MACqD,CAAC;AAExH,eAAO,MAAM,iBAAiB,UAAW,SAAS,GAAG,SAAS,KAAG,KAAK,IAAI,UAAU,GAAG,SAAS,EAC9B,CAAC;AAEnE,eAAO,MAAM,mBAAmB,UACvB,SAAS,GAAG,SAAS,QACtB,MAAM,SACL,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,KAC9C,IAgBF,CAAC"}
|