@hackylabs/deep-redact 4.0.0 → 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.
- package/README.md +9 -1
- package/dist/index.cjs +61 -22
- package/dist/index.js +61 -22
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ bun add @hackylabs/deep-redact
|
|
|
43
43
|
```json
|
|
44
44
|
{
|
|
45
45
|
"imports": {
|
|
46
|
-
"@hackylabs/deep-redact": "npm:@hackylabs/deep-redact@4.0.
|
|
46
|
+
"@hackylabs/deep-redact": "npm:@hackylabs/deep-redact@4.0.1"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
```
|
|
@@ -82,6 +82,8 @@ v4, v3, and fast-redact all return a plain JavaScript object.
|
|
|
82
82
|
|
|
83
83
|

|
|
84
84
|
|
|
85
|
+
_† fast-redact is a third-party library, not a deep-redact version. It is shown as a throughput reference; its feature set and guarantees differ from deep-redact's, so it is not a like-for-like comparison._
|
|
86
|
+
|
|
85
87
|
v4 is **~17× faster** than v3 on path-based workloads and **~10× faster** on wildcard workloads.
|
|
86
88
|
|
|
87
89
|
### Serialised output (`serialise: true`)
|
|
@@ -90,8 +92,14 @@ All four solutions return a JSON string.
|
|
|
90
92
|
|
|
91
93
|

|
|
92
94
|
|
|
95
|
+
_† fast-redact is a third-party library; json-stringify-regex is a naive native approach (`JSON.stringify(value).replace(pattern, replacement)`), not a library. Neither performs deep-redact's structured redaction or offers its guarantees, so both are shown as throughput references rather than like-for-like comparisons._
|
|
96
|
+
|
|
93
97
|
v4 remains faster than v3 in serialised mode. fast-redact and json-stringify-regex have a throughput advantage because their output path is oriented entirely toward string production.
|
|
94
98
|
|
|
99
|
+
Against deep-redact v2 the serialised picture is mixed: v4 is roughly at parity on path-based workloads but slower on breadth-heavy (wildcard) ones. That gap is the cost of safety v2 does not provide — under `serialise: true`, v4 runs the type transformers that make `BigInt`, `Date`, `Map`, `Set`, `Error`, `RegExp`, and `URL` values JSON-safe, and it detects and neutralises circular references instead of throwing on them. (Node and depth budgeting via `maxNodes`/`maxDepth` is opt-in and unlimited by default, so it adds nothing unless you enable it.)
|
|
100
|
+
|
|
101
|
+
These safety passes are intrinsic to `serialise: true` and cannot be switched off individually. If you do not need those guarantees and want to match v2's throughput (or better), set `serialise: false` and run your own `JSON.stringify`: the structured-output path skips the transformer and circular-reference passes entirely. This restores v2's trade-offs too — your `JSON.stringify` will throw on `BigInt` and circular references, `Map`/`Set` serialise as `{}`, and `undefined` is dropped.
|
|
102
|
+
|
|
95
103
|
Full speed and resource benchmark results: [`docs/benchmarks/speed-results.md`](docs/benchmarks/speed-results.md) and [`docs/benchmarks/resource-results.md`](docs/benchmarks/resource-results.md).
|
|
96
104
|
|
|
97
105
|
## Configuration
|
package/dist/index.cjs
CHANGED
|
@@ -2630,6 +2630,8 @@ const validateConfig = (options) => {
|
|
|
2630
2630
|
//#endregion
|
|
2631
2631
|
//#region src/core/replacement/serialise-output.ts
|
|
2632
2632
|
const bareIdentifierPattern = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
2633
|
+
const MAX_SERIALISE_DEPTH = 3e3;
|
|
2634
|
+
const NO_INDEX = -1;
|
|
2633
2635
|
const buildObjectChildPath = (parentPath, key) => {
|
|
2634
2636
|
if (!bareIdentifierPattern.test(key)) return `${parentPath ?? ""}["${key.replaceAll("\\", "\\\\").replaceAll("\"", String.raw`\"`)}"]`;
|
|
2635
2637
|
return parentPath === void 0 ? key : `${parentPath}.${key}`;
|
|
@@ -2642,26 +2644,49 @@ const isStrictDescendantPath = (ancestor, path) => {
|
|
|
2642
2644
|
if (ancestor === "") return true;
|
|
2643
2645
|
return path.startsWith(`${ancestor}.`) || path.startsWith(`${ancestor}[`);
|
|
2644
2646
|
};
|
|
2645
|
-
const
|
|
2647
|
+
const materialiseFramePath = (frame) => {
|
|
2648
|
+
const chain = [];
|
|
2649
|
+
for (let node = frame; node !== void 0; node = node.parent) chain.push(node);
|
|
2650
|
+
let path;
|
|
2651
|
+
for (let i = chain.length - 1; i >= 0; i -= 1) {
|
|
2652
|
+
const node = chain[i];
|
|
2653
|
+
if (node.index >= 0) path = buildArrayChildPath(path, node.index);
|
|
2654
|
+
else if (node.key !== void 0) path = buildObjectChildPath(path, node.key);
|
|
2655
|
+
}
|
|
2656
|
+
return path;
|
|
2657
|
+
};
|
|
2658
|
+
const materialiseStepPath = (parentFrame, key, index) => {
|
|
2659
|
+
const parentPath = materialiseFramePath(parentFrame);
|
|
2660
|
+
if (index >= 0) return buildArrayChildPath(parentPath, index);
|
|
2661
|
+
if (key !== void 0) return buildObjectChildPath(parentPath, key);
|
|
2662
|
+
return parentPath;
|
|
2663
|
+
};
|
|
2664
|
+
const materialiseAncestorPath = (frame, identity) => {
|
|
2665
|
+
for (let node = frame; node !== void 0; node = node.parent) if (node.identity === identity) return materialiseFramePath(node);
|
|
2666
|
+
};
|
|
2667
|
+
const buildSafeGraph = (value, transformers, seen, parentFrame, stepKey, stepIndex, cycleRegistry, depth) => {
|
|
2668
|
+
if (depth > MAX_SERIALISE_DEPTH) return "[UNSUPPORTED]";
|
|
2646
2669
|
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === void 0) return value;
|
|
2647
2670
|
if (typeof value === "function" || typeof value === "symbol") return "[UNSUPPORTED]";
|
|
2648
2671
|
const supportedKind = resolveSupportedTransformableValueKind(value);
|
|
2649
2672
|
if (supportedKind !== void 0) {
|
|
2650
2673
|
const runtimeIdentity = supportedKind === "bigint" ? void 0 : value;
|
|
2651
|
-
if (runtimeIdentity !== void 0) {
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2674
|
+
if (runtimeIdentity !== void 0 && seen.has(runtimeIdentity)) return {
|
|
2675
|
+
_transformer: "circular",
|
|
2676
|
+
path: materialiseStepPath(parentFrame, stepKey, stepIndex) ?? "",
|
|
2677
|
+
value: materialiseAncestorPath(parentFrame, runtimeIdentity) ?? ""
|
|
2678
|
+
};
|
|
2679
|
+
const frame = {
|
|
2680
|
+
parent: parentFrame,
|
|
2681
|
+
key: stepKey,
|
|
2682
|
+
index: stepIndex,
|
|
2683
|
+
identity: runtimeIdentity
|
|
2684
|
+
};
|
|
2685
|
+
if (runtimeIdentity !== void 0) seen.add(runtimeIdentity);
|
|
2661
2686
|
try {
|
|
2662
2687
|
const transformed = resolveTransformedValue(value, transformers);
|
|
2663
2688
|
if (transformed === void 0) return "[UNSUPPORTED]";
|
|
2664
|
-
return
|
|
2689
|
+
return buildTransformedGraph(transformed, transformers, seen, frame, cycleRegistry, depth + 1);
|
|
2665
2690
|
} catch {
|
|
2666
2691
|
return "[UNSUPPORTED]";
|
|
2667
2692
|
} finally {
|
|
@@ -2671,19 +2696,24 @@ const buildSafeGraph = (value, transformers, seen, identityPaths, currentPath, c
|
|
|
2671
2696
|
const identity = value;
|
|
2672
2697
|
if (seen.has(identity)) return {
|
|
2673
2698
|
_transformer: "circular",
|
|
2674
|
-
path:
|
|
2675
|
-
value:
|
|
2699
|
+
path: materialiseStepPath(parentFrame, stepKey, stepIndex) ?? "",
|
|
2700
|
+
value: materialiseAncestorPath(parentFrame, identity) ?? ""
|
|
2676
2701
|
};
|
|
2677
2702
|
if (cycleRegistry?.has(identity)) {
|
|
2678
2703
|
const registryPath = cycleRegistry.get(identity);
|
|
2679
|
-
|
|
2704
|
+
const currentPath = materialiseStepPath(parentFrame, stepKey, stepIndex) ?? "";
|
|
2705
|
+
if (isStrictDescendantPath(registryPath, currentPath)) return {
|
|
2680
2706
|
_transformer: "circular",
|
|
2681
|
-
path: currentPath
|
|
2707
|
+
path: currentPath,
|
|
2682
2708
|
value: registryPath
|
|
2683
2709
|
};
|
|
2684
2710
|
}
|
|
2685
|
-
const
|
|
2686
|
-
|
|
2711
|
+
const frame = {
|
|
2712
|
+
parent: parentFrame,
|
|
2713
|
+
key: stepKey,
|
|
2714
|
+
index: stepIndex,
|
|
2715
|
+
identity
|
|
2716
|
+
};
|
|
2687
2717
|
seen.add(identity);
|
|
2688
2718
|
try {
|
|
2689
2719
|
if (Array.isArray(value)) {
|
|
@@ -2691,18 +2721,18 @@ const buildSafeGraph = (value, transformers, seen, identityPaths, currentPath, c
|
|
|
2691
2721
|
result.length = value.length;
|
|
2692
2722
|
for (let index = 0; index < value.length; index += 1) {
|
|
2693
2723
|
if (!(index in value)) continue;
|
|
2694
|
-
result[index] = buildSafeGraph(value[index], transformers, seen,
|
|
2724
|
+
result[index] = buildSafeGraph(value[index], transformers, seen, frame, void 0, index, cycleRegistry, depth + 1);
|
|
2695
2725
|
}
|
|
2696
2726
|
return result;
|
|
2697
2727
|
}
|
|
2698
2728
|
if (isPlainObject$1(value)) {
|
|
2699
2729
|
const result = {};
|
|
2700
|
-
for (const key of Object.keys(value)) result[key] = buildSafeGraph(value[key], transformers, seen,
|
|
2730
|
+
for (const key of Object.keys(value)) result[key] = buildSafeGraph(value[key], transformers, seen, frame, key, NO_INDEX, cycleRegistry, depth + 1);
|
|
2701
2731
|
return result;
|
|
2702
2732
|
}
|
|
2703
2733
|
try {
|
|
2704
2734
|
const transformed = resolveTransformedValue(value, transformers);
|
|
2705
|
-
if (transformed !== void 0) return
|
|
2735
|
+
if (transformed !== void 0) return buildTransformedGraph(transformed, transformers, seen, frame, cycleRegistry, depth + 1);
|
|
2706
2736
|
} catch {
|
|
2707
2737
|
return "[UNSUPPORTED]";
|
|
2708
2738
|
}
|
|
@@ -2711,9 +2741,18 @@ const buildSafeGraph = (value, transformers, seen, identityPaths, currentPath, c
|
|
|
2711
2741
|
seen.delete(identity);
|
|
2712
2742
|
}
|
|
2713
2743
|
};
|
|
2744
|
+
const buildTransformedGraph = (transformed, transformers, seen, containerFrame, cycleRegistry, depth) => {
|
|
2745
|
+
if (isPlainObject$1(transformed) && typeof transformed._transformer === "string" && "value" in transformed) {
|
|
2746
|
+
const wrapper = transformed;
|
|
2747
|
+
const result = {};
|
|
2748
|
+
for (const key of Object.keys(wrapper)) result[key] = key === "value" ? buildSafeGraph(wrapper.value, transformers, seen, containerFrame, void 0, NO_INDEX, cycleRegistry, depth + 1) : buildSafeGraph(wrapper[key], transformers, seen, containerFrame, key, NO_INDEX, cycleRegistry, depth + 1);
|
|
2749
|
+
return result;
|
|
2750
|
+
}
|
|
2751
|
+
return buildSafeGraph(transformed, transformers, seen, containerFrame, void 0, NO_INDEX, cycleRegistry, depth + 1);
|
|
2752
|
+
};
|
|
2714
2753
|
const serialiseOutput = (value, transformers, serialise, cycleRegistry) => {
|
|
2715
2754
|
if (!serialise) return value;
|
|
2716
|
-
const safeGraph = value === void 0 ? "[UNSUPPORTED]" : buildSafeGraph(value, transformers, /* @__PURE__ */ new WeakSet(),
|
|
2755
|
+
const safeGraph = value === void 0 ? "[UNSUPPORTED]" : buildSafeGraph(value, transformers, /* @__PURE__ */ new WeakSet(), void 0, void 0, NO_INDEX, cycleRegistry, 0);
|
|
2717
2756
|
if (serialise === true) return JSON.stringify(safeGraph);
|
|
2718
2757
|
return serialise(safeGraph);
|
|
2719
2758
|
};
|
package/dist/index.js
CHANGED
|
@@ -2629,6 +2629,8 @@ const validateConfig = (options) => {
|
|
|
2629
2629
|
//#endregion
|
|
2630
2630
|
//#region src/core/replacement/serialise-output.ts
|
|
2631
2631
|
const bareIdentifierPattern = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
2632
|
+
const MAX_SERIALISE_DEPTH = 3e3;
|
|
2633
|
+
const NO_INDEX = -1;
|
|
2632
2634
|
const buildObjectChildPath = (parentPath, key) => {
|
|
2633
2635
|
if (!bareIdentifierPattern.test(key)) return `${parentPath ?? ""}["${key.replaceAll("\\", "\\\\").replaceAll("\"", String.raw`\"`)}"]`;
|
|
2634
2636
|
return parentPath === void 0 ? key : `${parentPath}.${key}`;
|
|
@@ -2641,26 +2643,49 @@ const isStrictDescendantPath = (ancestor, path) => {
|
|
|
2641
2643
|
if (ancestor === "") return true;
|
|
2642
2644
|
return path.startsWith(`${ancestor}.`) || path.startsWith(`${ancestor}[`);
|
|
2643
2645
|
};
|
|
2644
|
-
const
|
|
2646
|
+
const materialiseFramePath = (frame) => {
|
|
2647
|
+
const chain = [];
|
|
2648
|
+
for (let node = frame; node !== void 0; node = node.parent) chain.push(node);
|
|
2649
|
+
let path;
|
|
2650
|
+
for (let i = chain.length - 1; i >= 0; i -= 1) {
|
|
2651
|
+
const node = chain[i];
|
|
2652
|
+
if (node.index >= 0) path = buildArrayChildPath(path, node.index);
|
|
2653
|
+
else if (node.key !== void 0) path = buildObjectChildPath(path, node.key);
|
|
2654
|
+
}
|
|
2655
|
+
return path;
|
|
2656
|
+
};
|
|
2657
|
+
const materialiseStepPath = (parentFrame, key, index) => {
|
|
2658
|
+
const parentPath = materialiseFramePath(parentFrame);
|
|
2659
|
+
if (index >= 0) return buildArrayChildPath(parentPath, index);
|
|
2660
|
+
if (key !== void 0) return buildObjectChildPath(parentPath, key);
|
|
2661
|
+
return parentPath;
|
|
2662
|
+
};
|
|
2663
|
+
const materialiseAncestorPath = (frame, identity) => {
|
|
2664
|
+
for (let node = frame; node !== void 0; node = node.parent) if (node.identity === identity) return materialiseFramePath(node);
|
|
2665
|
+
};
|
|
2666
|
+
const buildSafeGraph = (value, transformers, seen, parentFrame, stepKey, stepIndex, cycleRegistry, depth) => {
|
|
2667
|
+
if (depth > MAX_SERIALISE_DEPTH) return "[UNSUPPORTED]";
|
|
2645
2668
|
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === void 0) return value;
|
|
2646
2669
|
if (typeof value === "function" || typeof value === "symbol") return "[UNSUPPORTED]";
|
|
2647
2670
|
const supportedKind = resolveSupportedTransformableValueKind(value);
|
|
2648
2671
|
if (supportedKind !== void 0) {
|
|
2649
2672
|
const runtimeIdentity = supportedKind === "bigint" ? void 0 : value;
|
|
2650
|
-
if (runtimeIdentity !== void 0) {
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2673
|
+
if (runtimeIdentity !== void 0 && seen.has(runtimeIdentity)) return {
|
|
2674
|
+
_transformer: "circular",
|
|
2675
|
+
path: materialiseStepPath(parentFrame, stepKey, stepIndex) ?? "",
|
|
2676
|
+
value: materialiseAncestorPath(parentFrame, runtimeIdentity) ?? ""
|
|
2677
|
+
};
|
|
2678
|
+
const frame = {
|
|
2679
|
+
parent: parentFrame,
|
|
2680
|
+
key: stepKey,
|
|
2681
|
+
index: stepIndex,
|
|
2682
|
+
identity: runtimeIdentity
|
|
2683
|
+
};
|
|
2684
|
+
if (runtimeIdentity !== void 0) seen.add(runtimeIdentity);
|
|
2660
2685
|
try {
|
|
2661
2686
|
const transformed = resolveTransformedValue(value, transformers);
|
|
2662
2687
|
if (transformed === void 0) return "[UNSUPPORTED]";
|
|
2663
|
-
return
|
|
2688
|
+
return buildTransformedGraph(transformed, transformers, seen, frame, cycleRegistry, depth + 1);
|
|
2664
2689
|
} catch {
|
|
2665
2690
|
return "[UNSUPPORTED]";
|
|
2666
2691
|
} finally {
|
|
@@ -2670,19 +2695,24 @@ const buildSafeGraph = (value, transformers, seen, identityPaths, currentPath, c
|
|
|
2670
2695
|
const identity = value;
|
|
2671
2696
|
if (seen.has(identity)) return {
|
|
2672
2697
|
_transformer: "circular",
|
|
2673
|
-
path:
|
|
2674
|
-
value:
|
|
2698
|
+
path: materialiseStepPath(parentFrame, stepKey, stepIndex) ?? "",
|
|
2699
|
+
value: materialiseAncestorPath(parentFrame, identity) ?? ""
|
|
2675
2700
|
};
|
|
2676
2701
|
if (cycleRegistry?.has(identity)) {
|
|
2677
2702
|
const registryPath = cycleRegistry.get(identity);
|
|
2678
|
-
|
|
2703
|
+
const currentPath = materialiseStepPath(parentFrame, stepKey, stepIndex) ?? "";
|
|
2704
|
+
if (isStrictDescendantPath(registryPath, currentPath)) return {
|
|
2679
2705
|
_transformer: "circular",
|
|
2680
|
-
path: currentPath
|
|
2706
|
+
path: currentPath,
|
|
2681
2707
|
value: registryPath
|
|
2682
2708
|
};
|
|
2683
2709
|
}
|
|
2684
|
-
const
|
|
2685
|
-
|
|
2710
|
+
const frame = {
|
|
2711
|
+
parent: parentFrame,
|
|
2712
|
+
key: stepKey,
|
|
2713
|
+
index: stepIndex,
|
|
2714
|
+
identity
|
|
2715
|
+
};
|
|
2686
2716
|
seen.add(identity);
|
|
2687
2717
|
try {
|
|
2688
2718
|
if (Array.isArray(value)) {
|
|
@@ -2690,18 +2720,18 @@ const buildSafeGraph = (value, transformers, seen, identityPaths, currentPath, c
|
|
|
2690
2720
|
result.length = value.length;
|
|
2691
2721
|
for (let index = 0; index < value.length; index += 1) {
|
|
2692
2722
|
if (!(index in value)) continue;
|
|
2693
|
-
result[index] = buildSafeGraph(value[index], transformers, seen,
|
|
2723
|
+
result[index] = buildSafeGraph(value[index], transformers, seen, frame, void 0, index, cycleRegistry, depth + 1);
|
|
2694
2724
|
}
|
|
2695
2725
|
return result;
|
|
2696
2726
|
}
|
|
2697
2727
|
if (isPlainObject$1(value)) {
|
|
2698
2728
|
const result = {};
|
|
2699
|
-
for (const key of Object.keys(value)) result[key] = buildSafeGraph(value[key], transformers, seen,
|
|
2729
|
+
for (const key of Object.keys(value)) result[key] = buildSafeGraph(value[key], transformers, seen, frame, key, NO_INDEX, cycleRegistry, depth + 1);
|
|
2700
2730
|
return result;
|
|
2701
2731
|
}
|
|
2702
2732
|
try {
|
|
2703
2733
|
const transformed = resolveTransformedValue(value, transformers);
|
|
2704
|
-
if (transformed !== void 0) return
|
|
2734
|
+
if (transformed !== void 0) return buildTransformedGraph(transformed, transformers, seen, frame, cycleRegistry, depth + 1);
|
|
2705
2735
|
} catch {
|
|
2706
2736
|
return "[UNSUPPORTED]";
|
|
2707
2737
|
}
|
|
@@ -2710,9 +2740,18 @@ const buildSafeGraph = (value, transformers, seen, identityPaths, currentPath, c
|
|
|
2710
2740
|
seen.delete(identity);
|
|
2711
2741
|
}
|
|
2712
2742
|
};
|
|
2743
|
+
const buildTransformedGraph = (transformed, transformers, seen, containerFrame, cycleRegistry, depth) => {
|
|
2744
|
+
if (isPlainObject$1(transformed) && typeof transformed._transformer === "string" && "value" in transformed) {
|
|
2745
|
+
const wrapper = transformed;
|
|
2746
|
+
const result = {};
|
|
2747
|
+
for (const key of Object.keys(wrapper)) result[key] = key === "value" ? buildSafeGraph(wrapper.value, transformers, seen, containerFrame, void 0, NO_INDEX, cycleRegistry, depth + 1) : buildSafeGraph(wrapper[key], transformers, seen, containerFrame, key, NO_INDEX, cycleRegistry, depth + 1);
|
|
2748
|
+
return result;
|
|
2749
|
+
}
|
|
2750
|
+
return buildSafeGraph(transformed, transformers, seen, containerFrame, void 0, NO_INDEX, cycleRegistry, depth + 1);
|
|
2751
|
+
};
|
|
2713
2752
|
const serialiseOutput = (value, transformers, serialise, cycleRegistry) => {
|
|
2714
2753
|
if (!serialise) return value;
|
|
2715
|
-
const safeGraph = value === void 0 ? "[UNSUPPORTED]" : buildSafeGraph(value, transformers, /* @__PURE__ */ new WeakSet(),
|
|
2754
|
+
const safeGraph = value === void 0 ? "[UNSUPPORTED]" : buildSafeGraph(value, transformers, /* @__PURE__ */ new WeakSet(), void 0, void 0, NO_INDEX, cycleRegistry, 0);
|
|
2716
2755
|
if (serialise === true) return JSON.stringify(safeGraph);
|
|
2717
2756
|
return serialise(safeGraph);
|
|
2718
2757
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hackylabs/deep-redact",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Deeply redact sensitive data from objects, arrays and arbitrary strings (e.g. XML or raw cookies data) with a composable, function-first API.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"url": "git+https://github.com/hackylabs/deep-redact"
|
|
61
61
|
},
|
|
62
62
|
"//": [
|
|
63
|
-
"deep-redact-v3 and fast-redact are installed only as internal benchmark comparisons and are not used in the library",
|
|
63
|
+
"deep-redact-v2, deep-redact-v3, deep-redact-v4-baseline (released 4.0.0) and fast-redact are installed only as internal benchmark comparisons and are not used in the library",
|
|
64
64
|
"all dependencies are for development purposes only"
|
|
65
65
|
],
|
|
66
66
|
"devDependencies": {
|
|
@@ -68,7 +68,9 @@
|
|
|
68
68
|
"@stylistic/eslint-plugin": "4.4.1",
|
|
69
69
|
"@types/fast-redact": "3.0.4",
|
|
70
70
|
"@types/node": "24.1.0",
|
|
71
|
+
"deep-redact-v2": "npm:@hackylabs/deep-redact@2.2.1",
|
|
71
72
|
"deep-redact-v3": "npm:@hackylabs/deep-redact@^3.0.0",
|
|
73
|
+
"deep-redact-v4-baseline": "npm:@hackylabs/deep-redact@4.0.0",
|
|
72
74
|
"eslint": "9.39.4",
|
|
73
75
|
"eslint-plugin-unicorn": "59.0.1",
|
|
74
76
|
"fast-redact": "3.5.0",
|