{"_id":"@asaidimu/utils-sanitize","_rev":"15-18acd29ea7ec5a26d5e128cd5c8da5bc","name":"@asaidimu/utils-sanitize","dist-tags":{"latest":"2.0.1"},"versions":{"1.0.0":{"name":"@asaidimu/utils-sanitize","version":"1.0.0","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.0","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"6ae0c7b2d9a3f70c914a19e9213f0f4639c9d92e","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.0.tgz","fileCount":7,"integrity":"sha512-b9jy3EO81SG/df77s+vrkl0TMlhUxGzcSC3CdMDN29mX7KxJJ6eRglcYJRfQqBc69K4toKSQHzQN2eF2cCAsoA==","signatures":[{"sig":"MEUCIQC1Rhqr8OYBZXkAmd2lfCyv1GUIgar+zWgeau+31T8vXQIgEo6aqCLHYheCv+i6P/uk3aOLGMgVYVxxUSYPXt3zHSc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49106},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"0ecbd5a5d965d79b392960da1a0d75796072bb14","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.0_1782052441523_0.7924167334754386","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@asaidimu/utils-sanitize","version":"1.0.1","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.1","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"829c06e07379845065f8a6988a3a4016500d7dd7","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.1.tgz","fileCount":7,"integrity":"sha512-KO3byeQnZtJVxWC+ylEP2+eioOrvLb9CrvAzPCHlKKywswopjANhcHOR8/0L1CFuXOVKYSkJmNRWuHTK/Tb2GA==","signatures":[{"sig":"MEQCIDddiZWPpxjcTmhY/l6zzsnJXyOPeWjfitsvUIZJGRuDAiBFNzTrVHZ0Roac5fSzYPDepm+pwwY8AaN6xSDHy+/yCA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49213},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"42fb679e62f51b214ced571d5c2b7211d895499d","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.4"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.1_1782113576582_0.9823193662580711","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@asaidimu/utils-sanitize","version":"1.0.2","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.2","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"677a23896c83c3be5115181ab5301516c71b1969","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.2.tgz","fileCount":7,"integrity":"sha512-kX4Wiu21sbFyDiedY0eRXJJg+C8UysI/b7xBtQD0uZ2tgmQMQEsX65rvfpIsx/h7HwEuClwkln+h3vrt5DTbFQ==","signatures":[{"sig":"MEUCIFTSIJF1QLcWVMOX6vr3IUl2IddJ7ZGnQ1gU+2EFqwoBAiEA+Ymmkii98nGahEPtBU3yFSDpbFZLEPcaGYqfsjYEyNc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49213},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"7793208856c002fb8260b9dbf1b5a4c91eae9428","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.5"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.2_1782114850817_0.17034350054651526","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@asaidimu/utils-sanitize","version":"1.0.3","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.3","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"05523663c154a8eeb7845efc17c15967598865cc","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.3.tgz","fileCount":7,"integrity":"sha512-0jcvKQT1bcu68wMnDhay0myKEPXf10f47wlzpf1H1hOu9s4p1ah4/CI8bf9lxLAgSRqExgGo9BQbpd1z3JejBQ==","signatures":[{"sig":"MEQCIHLaVhckjPb0yspVas5kzDE8wpFg21z9XyIxp7waX79CAiAKMliY8tMKVsBha3mhXJ2SHy9W02nCI9Hsy8xQNnkfZQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49213},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"ff8d6b6e1856ed7aaa6279f96a8e06140b423758","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.6"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.3_1782115533175_0.9252609580596207","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@asaidimu/utils-sanitize","version":"1.0.4","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.4","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"8e2757118ad571960d7c22f8725adfcebfdf1a40","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.4.tgz","fileCount":7,"integrity":"sha512-DFfNw1r61q+zlwrIrsix9CZwmhPaxSsflsoHvL9cAzNLDF3hYjbpCUZGWwSNCjHxjq11zIfZtyu2KrFLGeg8ig==","signatures":[{"sig":"MEUCIDNE55xfM/0AtNtHyNJx4DZAtL/2QU3lyasJbETtGTOqAiEA0No6ABdlkIe5UhWTngt0H20IiLvQxATYNuxLXl6I3SY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50140},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"31cddfcc43c2fd8d0aade08a71e4c120320fff7b","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@asaidimu/utils-error":"1.1.4","@asaidimu/utils-logger":"1.0.7"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.4_1782224034247_0.9169037475440034","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@asaidimu/utils-sanitize","version":"1.0.5","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.5","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"0cfb6d1da73d3b69f97a7f8d7a96413235a50051","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.5.tgz","fileCount":7,"integrity":"sha512-PdG1iazcCg9ZYMqy7T0EIlYTY7MoysAZx0Vig6t0MkUeHqrHEo+IXjHk5tBJJ8BW6ZtyxrPgz2wX/+XT3tK//w==","signatures":[{"sig":"MEUCIQDRcGGGau5cW/3KzeCgETpbyKSbZvk2WOJhkcb7oGik/QIgTgpf7gUK6i95/esUSNFCR3Ly2wW70+e0D4RzdIn1IU4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50142},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"552e4fcc8afb101af3f040452eb23dec7e8aa3f4","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.8"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.5_1782229144563_0.19829898989184236","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@asaidimu/utils-sanitize","version":"1.0.6","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.6","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"1c283c5a4b602ca2eb596ffd9c14db569a3c3fd2","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.6.tgz","fileCount":7,"integrity":"sha512-oXE6waZUd+tZzDtLII2BUMKx9EnAGnUsCLSbMkUlqqCmMc04YwoBMCkx/rLeiyLUK7Dktjec4gzetv9YBAuBcw==","signatures":[{"sig":"MEUCIQCmRQRu2N10wxhFd9SpfnEfNxm5JdSl8GAOsqQoqoRm+AIgCFEMYdT4/LRMXkqMW7Mp/9LH3LgEesH1Yip9Zfsxg8Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67534},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"1c7c00be6b478461af493b3b0313a565f9e1c60f","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.9"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.6_1782313550075_0.15785394753371285","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@asaidimu/utils-sanitize","version":"1.0.7","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.7","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"c84da7ba386dc35bb64dcf4b9f7766fbc312044b","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.7.tgz","fileCount":7,"integrity":"sha512-Zk6a6xsZvAZfaIFVUlBzvxTrk7W3px5e6dfO4sN+p2qhEYZ/YcrPGnUCvtyH8RJ9MvWvgbsuPepQzxqEnZ6j6A==","signatures":[{"sig":"MEUCIQC2WJ3j87EF97QlG6XIeulYrKjCcNuxWmbw2UyFv111fwIgViSwVC0S0wWIGF9dd+eGmV9RpHdbW7xUrmUxFU+rfO0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67516},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"eba6641a64a634f71dea90df1171ae725a219e52","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.9"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.7_1782316618960_0.7366065483465729","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@asaidimu/utils-sanitize","version":"1.0.8","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.8","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"5fb65a52aeb1af836a9a28927bfe87f0149d385d","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.8.tgz","fileCount":7,"integrity":"sha512-RWSFUwmK2qQnl8PD9MwWICrbZhlKp+j4AjrA4Jmq4cLV7S8O2bByHz7nvcnj3nAI2A9lJBfi2lAUtPgVnStpIQ==","signatures":[{"sig":"MEUCIQDQRavOF4y6yEbFfrzfzU4ywj42FNZOSCD15pNMQVeoWQIgLz2Vid5CyOBbCp40cYK2CE32ce1MUc03o2x+3wijf3k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67714},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"0ee476514f34d81d39e8aac1208af31be960116f","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.9"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.8_1782397445511_0.031030973321720223","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@asaidimu/utils-sanitize","version":"1.0.9","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.9","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"bb6b1471fb972e668205e2584adbd54351339c21","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.9.tgz","fileCount":7,"integrity":"sha512-2nurqFPP+B/iozmaB+wMoqNIokyOiygLO8sfz4JF0Mad+s1GoI3cn/2PD79+SNbFAhGT0F9eNmb4XM/39X3hcA==","signatures":[{"sig":"MEYCIQCO5RWE9XVA76Flr8OiYSjZThjXE3432CWxENYoR5KsZgIhAIZVNVEgRiiCBcW53ExPrPQ9b+eNjZnuxnbRwYqv0KU9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":66315},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"6a0b0a3932740d1fd7b9dfbd3e6a35ba3c8f4760","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.11"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.9_1782403966473_0.6423161394075023","host":"s3://npm-registry-packages-npm-production"}},"1.0.10":{"name":"@asaidimu/utils-sanitize","version":"1.0.10","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.10","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"4b1e9a8a8b4f01749dcad814a30b77a998368507","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.10.tgz","fileCount":7,"integrity":"sha512-jk4tuvoAqu/G8W4E6IlpCM/VfuGg7p0xWtcVzgzn/rgvmgLDYNal/ADXS3u69PuLAjrq0S14wPQstYkhol1EwA==","signatures":[{"sig":"MEUCIBQXILDshyBUdYtu6N+pLspY8Ylx46+15wJ29OkAKkhjAiEAxcc/26UoPucKzXyvfiHoyWUgArafv1pq6H6nyIAFx1I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64607},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"a07dc3881f255731593eb98111d47d8f544cf8ba","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.11"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.10_1783754492480_0.1520449320121311","host":"s3://npm-registry-packages-npm-production"}},"1.0.11":{"name":"@asaidimu/utils-sanitize","version":"1.0.11","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.11","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"c5eb85d7e53a14cfe8613568c0279fdfbfced03a","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.11.tgz","fileCount":7,"integrity":"sha512-SLzd9sB7QzV68KuCURI5Kbz9xwW3+oddoQOUgo6z5LvxMHcqnW9QNZoTw+0rRTxnCAh6rCQmsa+Ucvp3Bszcfw==","signatures":[{"sig":"MEQCICwhniNf4n3/U1Usf8Zy9j5U+wOHGk3GmOzm6cuLLEevAiB41Bj7oqL8Xxsyqz35L8FaWa9rqulXteSsD2cOfPWm2Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102348},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"7ff89643400d2cc2c6b8b2dd03a5ed5ae747c88d","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.12"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.11_1783861799065_0.139317098867201","host":"s3://npm-registry-packages-npm-production"}},"1.0.12":{"name":"@asaidimu/utils-sanitize","version":"1.0.12","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@1.0.12","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"5552a52069392988809b77852dfb1edd4d317d71","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-1.0.12.tgz","fileCount":7,"integrity":"sha512-AKHGnCU6Qec9oYjmadimwTqukNyejkHb1XXci726g7gc/ftR97NbTV/c1L41+oblbExAyBGm0SfjpWQFH54ApA==","signatures":[{"sig":"MEYCIQCXIGzBdX4OLKnA4uNQwps2vnT8w+UqPdFur6I8jVwY6QIhAJSc4jU9iIsealWcUcnsrpHT44L82V5R8H+DoRvHiySG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102348},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"36641becbcdf209d738deab1a5db9251257130e0","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.13"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_1.0.12_1783863114512_0.6575408465575028","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@asaidimu/utils-sanitize","version":"2.0.0","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","_id":"@asaidimu/utils-sanitize@2.0.0","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"dist":{"shasum":"0352c1b6ba649d95ec4f7d05ab1c3bfbdfb23ae9","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-2.0.0.tgz","fileCount":7,"integrity":"sha512-yxmbxrowqXFU/uyrGY5fkl1YWOhAibgEJCUCKaCZw55Usw3ApKiHM4wI8RMvQoB28i2LAneeELhIqt1t2iZI5w==","signatures":[{"sig":"MEQCIG0EctqR8BWgOu2RkLchMbkUbVUh9Z9rOYkZcbzQ9pkBAiB0dm/3cD7oekev7yMQ8rYd+5qb56EqeUMeWS6MZbtPKQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102347},"main":"index.js","types":"index.d.ts","module":"index.mjs","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"gitHead":"2c4b26dcfa6faa9f4bf1c2eeecea43a370b293b2","release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"repository":{"url":"git+https://github.com/asaidimu/erp-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"A collection of sanitize utilities.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^1.0.14"},"publishConfig":{"tag":"latest","access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/utils-sanitize_2.0.0_1788167500991_0.2746765159782696","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@asaidimu/utils-sanitize","version":"2.0.1","description":"A collection of sanitize utilities.","main":"index.js","module":"index.mjs","types":"index.d.ts","keywords":["typescript","utility"],"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/asaidimu/erp-utils.git"},"bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","exports":{".":{"import":{"types":"./index.d.ts","default":"./index.mjs"},"require":{"types":"./index.d.ts","default":"./index.js"}}},"dependencies":{"@asaidimu/utils-error":"^1.0.0","@asaidimu/utils-logger":"^2.0.0"},"publishConfig":{"registry":"https://registry.npmjs.org/","tag":"latest","access":"public"},"release":{"plugins":[["@semantic-release/npm",{"pkgRoot":"./dist"}],["@semantic-release/git",{"assets":["CHANGELOG.md","package.json"],"message":"chore(release): Release @asaidimu/utils-sanitize v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}]]},"peerDependencies":{},"_id":"@asaidimu/utils-sanitize@2.0.1","gitHead":"220984dc389d2f8eaa08580521b12b2e6bb78562","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-WsDLeLX26WK9aoLoY7lOiz6ZFht3VU405TWM1+dc1WvvxZkmKtM4BdznCf7CkAy7exfpm32cDfi6Mmcpw1UHVg==","shasum":"785d9364947344d3d36d4d74bfafbed5219bec33","tarball":"https://registry.npmjs.org/@asaidimu/utils-sanitize/-/utils-sanitize-2.0.1.tgz","fileCount":7,"unpackedSize":102346,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHBKEN+2+4NCUhpYUTYdguPAQLrMTjROQ+Sv3gpPrREJAiEAhehICL6VjQx1VRFSCHjvEPAl9kywxgod7+vANX5nfZ4="}]},"_npmUser":{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"},"directories":{},"maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/utils-sanitize_2.0.1_1789153564978_0.5862957361895984"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-21T14:34:01.348Z","modified":"2026-09-11T19:06:05.282Z","1.0.0":"2026-06-21T14:34:01.671Z","1.0.1":"2026-06-22T07:32:56.718Z","1.0.2":"2026-06-22T07:54:10.974Z","1.0.3":"2026-06-22T08:05:33.297Z","1.0.4":"2026-06-23T14:13:54.372Z","1.0.5":"2026-06-23T15:39:04.728Z","1.0.6":"2026-06-24T15:05:50.218Z","1.0.7":"2026-06-24T15:56:59.093Z","1.0.8":"2026-06-25T14:24:05.674Z","1.0.9":"2026-06-25T16:12:46.592Z","1.0.10":"2026-07-11T07:21:32.619Z","1.0.11":"2026-07-12T13:09:59.221Z","1.0.12":"2026-07-12T13:31:54.632Z","2.0.0":"2026-08-31T09:11:41.104Z","2.0.1":"2026-09-11T19:06:05.151Z"},"bugs":{"url":"https://github.com/asaidimu/erp-utils/issues"},"author":{"name":"Saidimu","email":"47994458+asaidimu@users.noreply.github.com"},"license":"MIT","homepage":"https://github.com/asaidimu/erp-utils/tree/main/src/sanitize#readme","keywords":["typescript","utility"],"repository":{"type":"git","url":"git+https://github.com/asaidimu/erp-utils.git"},"description":"A collection of sanitize utilities.","maintainers":[{"name":"asaidimu","email":"lolokilesaidimu@gmail.com"}],"readme":"# `@asaidimu/utils-sanitize`\n\nField-level sanitization for documents, with support for configurable masking policies, recursive deep sanitization, multi-scope configuration merging, and HMAC-based hashing. Works in browsers and Node.js 18+ (Web Crypto API).\n\n## Installation\n\n```bash\nnpm install @asaidimu/utils-sanitize\n```\n\n## Quick Start\n\n```typescript\nimport {\n  DocumentSanitizer,\n  newSecureDefaultConfig,\n  commonEnvPatterns,\n} from \"@asaidimu/utils-sanitize\";\n\n// Create a sanitizer with common security patterns + env var value masking\nconst config = newSecureDefaultConfig();\nconfig.patterns = [...config.patterns!, ...commonEnvPatterns([\"DATABASE_URL\"])];\nconst sanitizer = new DocumentSanitizer(config, \"my-scope\");\n\nconst doc = {\n  username: \"alice\",\n  password: \"supersecret\",\n  email: \"alice@example.com\",\n  ssn: \"123-45-6789\",\n  k: process.env.API_KEY, // caught by value-pattern even though key is \"k\"\n  notes: \"hello world\",\n};\n\nconst result = await sanitizer.sanitizeDocumentDeep(doc);\n// {\n//   username: \"alice\",\n//   password: \"***\",\n//   email:    \"al*********om\",\n//   ssn:      \"***\",\n//   k:        \"***\",\n//   notes:    \"hello world\",\n// }\n```\n\n## Policies\n\n| Policy       | Constant       | Effect                                                                          |\n| ------------ | -------------- | ------------------------------------------------------------------------------- |\n| `\"redact\"`   | `MaskRedact`   | Replaces value with `\"***\"`                                                     |\n| `\"hash\"`     | `MaskHash`     | Replaces value with `[HASH:XXXXXXXX]` (first 8 hex chars of HMAC-SHA256)        |\n| `\"obscure\"`  | `MaskObscure`  | Shows prefix/suffix characters, replaces middle with a character (default: `*`) |\n| `\"preserve\"` | `MaskPreserve` | Leaves the value unchanged (default)                                            |\n\n### Policy Resolution\n\nEvery field goes through `resolvePolicy(fieldName, value)`, which walks **all** matching rules and returns the most restrictive result — it never short-circuits on the first match.\n\nResolution collects candidates from three sources:\n\n1. **Explicit field mapping** (`config.fields`) — keyed by exact field name\n2. **Key-patterns** (`matchOn: \"key\"`) — tested against the field name\n3. **Value-patterns** (`matchOn: \"value\"`) — tested against the string representation of the field value, regardless of key name\n\nThe most restrictive policy across all matches wins. For example, if a key-pattern resolves to `\"obscure\"` but a value-pattern resolves to `\"redact\"`, the field is redacted.\n\n### Restrictiveness Ordering\n\n`redact > hash > obscure > preserve`\n\nUse `mostRestrictivePolicy(a, b)` to get the more restrictive of two policies.\n\n## Input Normalization\n\nBefore any policy is applied, all document entry points normalize the input through `toPojo`. This ensures the sanitizer output is always a serialization-safe plain object, since the output is assumed to be serialized (e.g. via `JSON.stringify`).\n\n**Normalization rules (applied recursively):**\n\n- **Own string keys only** — inherited properties and symbol-keyed properties are discarded\n- **Functions are dropped** — function-valued keys are removed entirely; function elements inside arrays are compacted out\n- **Symbols are dropped** — same treatment as functions\n- **`null` / `undefined`** — preserved as-is\n- **`Date` / `Uint8Array`** — treated as leaf scalars, returned unchanged\n- **Arrays** — recursed element-by-element; non-serializable elements (functions, symbols) are removed, compacting the array\n- **All other objects** — own string keys only, recursed into, producing a plain `Record`\n- **Primitives** (`string`, `number`, `boolean`, `bigint`) — pass through unchanged\n\n## API\n\n### Core Types\n\n```typescript\ntype MaskedFieldPolicy = \"redact\" | \"hash\" | \"preserve\" | \"obscure\";\n```\n\n### `Sanitizer`\n\nFlat-document sanitizer. Applies policies to top-level fields only.\n\n```typescript\nconst s = new Sanitizer(config, logger?);\n\n// Sanitize a single value\nawait s.sanitizeValue(\"fieldName\", value);\n\n// Sanitize a flat document (input is normalized via toPojo)\nawait s.sanitizeDocument({ field: value, ... });\n```\n\n### `DocumentSanitizer`\n\nExtends `Sanitizer` with recursive deep sanitization and metadata handling.\n\n```typescript\nconst ds = new DocumentSanitizer(config, scopeID, logger?);\n\n// Deep sanitization (nested objects, arrays; input normalized via toPojo)\nawait ds.sanitizeDocumentDeep(doc);\n\n// Sanitize only metadata (preserves reserved system fields)\nawait ds.sanitizeMetadata(metadata);\n```\n\n**Deep sanitization behaviour:**\n\n- **Plain objects** — recursed, each key sanitized independently (policies are not inherited from parent field names)\n- **Arrays** — recursed element-by-element\n  - Objects inside arrays have each key sanitized independently\n  - Scalars inside arrays inherit the parent field's policy via `<fieldName>[]` lookup\n- **Dates** and **Uint8Arrays** — treated as scalars (not recursed)\n- **`_metadata_`** — special handling: system fields (`_version_`, `_created_`, `_updated_`, `_checksum_`, `_signature_`) are preserved; user-defined fields are sanitized\n\n### `FieldMaskConfig`\n\n```typescript\ninterface FieldMaskConfig {\n  version?: string;\n  scope?: string;\n  defaultPolicy?: MaskedFieldPolicy; // default: \"preserve\"\n  fields?: Record<string, MaskedFieldPolicy>;\n  patterns?: PatternRule[];\n  obscureConfig?: ObscureConfig;\n  hashSecret?: string; // hex-encoded, ≥ 32 hex chars\n  description?: string;\n}\n```\n\n### `ObscureConfig`\n\n```typescript\ninterface ObscureConfig {\n  prefixLength: number; // chars to show at start (default: 2)\n  suffixLength: number; // chars to show at end (default: 2)\n  replacement: string; // middle replacement char (default: \"*\")\n  maxLength: number; // normalize output length (0 = no limit, default: 0)\n}\n```\n\nWhen `maxLength` is set, the output is normalised to exactly `maxLength`, hiding the original value's length:\n\n| Original            | `maxLength=12`   | Notes           |\n| ------------------- | ---------------- | --------------- |\n| `\"abc123\"`          | `\"ab******23\"`   | Padded to 12    |\n| `\"1ea82440-9c3e\"`   | `\"1ea8****9c3e\"` | Exact fit       |\n| `\"1ea82440-…-2651\"` | `\"1ea8****2651\"` | Truncated to 12 |\n\nValues shorter than `prefixLength + suffixLength + 1` are rendered as `\"[OBSCURED]\"`.\n\n### `PatternRule`\n\n```typescript\ninterface PatternRule {\n  pattern: string; // regex source string\n  policy: MaskedFieldPolicy;\n  matchOn?: \"key\" | \"value\"; // default: \"key\"\n  comment?: string; // human-readable description\n  readonly _regex?: RegExp; // compiled regex (non-enumerable, internal)\n}\n```\n\n`matchOn` controls what the pattern is tested against:\n\n- `\"key\"` — pattern is tested against the field name. Used by `commonSecurityPatterns()`.\n- `\"value\"` — pattern is tested against the string representation of the field value, regardless of key name. Used by `commonEnvPatterns()` to catch cases like `{ k: process.env.API_KEY }` where the key carries no signal.\n\nBoth kinds of rules participate in the same `resolvePolicy` pass, with the most restrictive match across all rules winning.\n\n### Config Validation\n\n`validateConfig(config)` validates a `FieldMaskConfig`, mutating it to apply defaults. Throws `SystemError` aggregating all validation errors when any are found (severity: `\"error\"`). Warnings (e.g., `maxLength` too small) are collected but do not throw. Also validates `matchOn` when present.\n\n### Configuration Merging\n\n```typescript\nmergeConfigs(globalConfig, scopedConfig): FieldMaskConfig\n```\n\nMerges a global config with a scoped config for multi-scope setups:\n\n- **Fields** — global baseline, scoped overrides (scoped wins on collision)\n- **Patterns** — scoped patterns evaluated first (higher priority); a scoped pattern shadows a global pattern only when both have the same `matchOn` **and** the same regex source. A `\"key\"` pattern and a `\"value\"` pattern with the same regex are treated as distinct rules and never collapse.\n- **Default policy** — scoped wins, then global, then `\"preserve\"`\n- **Obscure config** — scoped wins when it has a `replacement` char\n- **Hash secret** — scoped wins\n\nDoes not mutate either input.\n\n### Helpers\n\n```typescript\n// Field policy parsing\nparseMaskedFieldPolicy(s: string): MaskedFieldPolicy;  // throws SystemError on invalid\n\n// Policy comparison\nmostRestrictivePolicy(a, b): MaskedFieldPolicy;\n\n// Input normalization\ntoPojo(value: unknown): unknown;  // recursively normalize to serialization-safe POJO\n\n// Pattern compilation\ncompilePattern(pattern, policy, comment?, matchOn?): PatternRule;     // throws on invalid regex\nmustCompilePattern(pattern, policy, comment?, matchOn?): PatternRule; // alias (for static init)\n\n// Pre-built key-name patterns\ncommonSecurityPatterns(): PatternRule[];   // 11 patterns matched against field names\nnewSecureDefaultConfig(): FieldMaskConfig; // config with common patterns + defaults\n\n// Pre-built value patterns from environment variables\ncommonEnvPatterns(extraKeys?: string[], env?: Record<string, string | undefined>): PatternRule[];\n\n// Batch sanitization\nsanitizeDocumentArray(sanitizer, docs[]): Promise<Record<string, unknown>[]>;\nsanitizeValue(sanitizer, value): Promise<unknown>; // auto-detect object/array/scalar\n```\n\n### `commonSecurityPatterns()` — included patterns\n\nAll rules use `matchOn: \"key\"` — they match against field names.\n\n| Pattern                    | Policy    | Field examples                 |\n| -------------------------- | --------- | ------------------------------ |\n| `password`                 | `redact`  | `password`, `userPassword`     |\n| `secret`                   | `redact`  | `secret`, `my_secret`          |\n| `token`                    | `redact`  | `token`, `auth_token`          |\n| `api[_-]?key`              | `redact`  | `api_key`, `apikey`, `api-key` |\n| `private[_-]?key`          | `redact`  | `private_key`                  |\n| `credential`               | `redact`  | `credential`, `credentials`    |\n| `ssn\\|social[_-]?security` | `redact`  | `ssn`, `social_security`       |\n| `credit[_-]?card\\|cvv`     | `redact`  | `credit_card`, `cvv`           |\n| `email`                    | `obscure` | `email`, `userEmail`           |\n| `phone\\|mobile`            | `obscure` | `phone`, `mobile`              |\n| `auth`                     | `hash`    | `auth`, `authToken`            |\n\n### `commonEnvPatterns(extraKeys?, env?)` — value patterns from env\n\nBuilds `matchOn: \"value\"` rules from environment variables so that any field whose **value** equals a known secret is redacted, regardless of key name. This catches patterns like `{ k: process.env.API_KEY }` where the key carries no signal.\n\n```typescript\nconst config = newSecureDefaultConfig();\nconfig.patterns = [\n  ...config.patterns!,\n  // heuristic: all env vars whose name contains key, secret, token, etc.\n  // + any explicitly named vars\n  ...commonEnvPatterns([\"DATABASE_URL\"]),\n];\n```\n\nHow rules are built:\n\n1. Collects env var names whose name matches the heuristic (`key`, `secret`, `token`, `password`, `passwd`, `credential`, `auth`, `api`, `private`, `cert`, `signing` — case-insensitive)\n2. Merges in `extraKeys`; deduplicates by name\n3. Skips values shorter than 8 characters (too short — high false-positive risk)\n4. Deduplicates by resolved value — two vars holding the same secret produce one rule\n5. Escapes each value as a literal regex so special characters do not alter matching semantics\n6. Returns `PatternRule[]` with `matchOn: \"value\"` and `policy: \"redact\"`\n\nThe optional `env` parameter (default: `process.env`) accepts any `Record<string, string | undefined>`, making the function fully testable without real environment state:\n\n```typescript\nconst rules = commonEnvPatterns([\"MY_KEY\"], { MY_KEY: \"super-secret-value\" });\n// → one PatternRule, matchOn \"value\", literal pattern \"super\\-secret\\-value\"\n```\n\n## Hash Details\n\n- Uses **HMAC-SHA256** via the Web Crypto API (`crypto.subtle.sign`)\n- Output format: `[HASH:XXXXXXXX]` (first 8 hex chars)\n- Each `Sanitizer` instance uses a per-instance random 32-byte secret when `hashSecret` is not provided, preventing rainbow-table attacks\n- Consistent secret across instances = consistent hashes for the same input values\n\n## Obscure Details\n\n- Uses `TextDecoder` for `Uint8Array` values\n- Falls back to `String()` for all other non-string types\n- With `maxLength > 0`, the output is normalised to exactly `maxLength` characters, hiding the original length\n\n## Error Handling\n\nThe module throws `SystemError` (from `@core/error`) with structured error codes:\n\n| Code                               | Scenario                                        |\n| ---------------------------------- | ----------------------------------------------- |\n| `ERR_SANITIZATION_CONFIG_INVALID`  | Config validation failed                        |\n| `ERR_INVALID_POLICY`               | Unknown policy string                           |\n| `ERR_INVALID_MATCH_ON`             | `matchOn` value is not `\"key\"` or `\"value\"`     |\n| `ERR_EMPTY_PATTERN`                | Pattern string is empty                         |\n| `ERR_INVALID_REGEX`                | Pattern regex failed to compile                 |\n| `ERR_INVALID_CONFIG`               | Invalid obscure config or hash secret           |\n| `ERR_SANITIZATION_PATTERN_INVALID` | `compilePattern` received invalid regex         |\n| `ERR_SANITIZATION_INVALID_INPUT`   | Top-level document is not a plain object        |\n| `ERR_SANITIZATION_FAILED`          | Document sanitization failed (batch operations) |\n\nOn invalid config, `Sanitizer` and `DocumentSanitizer` constructors fall back to a **preserve-all** default and log the error — they never throw from the constructor.\n","readmeFilename":"README.md"}