{"_id":"@doist/piiranha","_rev":"5-66fbf59e63c39961ff39996a1060991a","name":"@doist/piiranha","dist-tags":{"latest":"3.5.8"},"versions":{"0.0.1":{"name":"@doist/piiranha","version":"0.0.1","keywords":["oidc","trusted-publishing","setup"],"_id":"@doist/piiranha@0.0.1","maintainers":[{"name":"ricardoist","email":"ricardo@doist.com"},{"name":"henningmu","email":"muszynski.henning@gmail.com"},{"name":"jvalente","email":"joao@doist.com"},{"name":"antondoist","email":"antonball@doist.com"},{"name":"jefcurtis","email":"jef@doist.com"},{"name":"doistbot","email":"dev@doist.com"},{"name":"fbidu","email":"felipe@doist.com"},{"name":"goncalossilva","email":"goncalossilva@gmail.com"},{"name":"omar.doist.com","email":"omar@doist.com"},{"name":"itsevertv","email":"evert@doist.com"},{"name":"scottatdoist","email":"scott@doist.com"},{"name":"ernestodoist","email":"ernesto@doist.com"}],"dist":{"shasum":"9157ef6c84d0159c0d0b583d3a0318be863a67db","tarball":"https://registry.npmjs.org/@doist/piiranha/-/piiranha-0.0.1.tgz","fileCount":2,"integrity":"sha512-lx7ZjUT8rTt17UN+hlak2yDwFWIgD+LD1xRhkQcE+sIofQE5zso40WpVPg/OwCMXBH3lJZY9ItJI/VExspwyxg==","signatures":[{"sig":"MEUCIDqQtt8y4iGQ1uttwTXR5S6KnoQYkEorqe1ltIRO8Us8AiEA6q1zKJTF013nDRQY4hPZ7WADyMY4E453HVC6qq9ZbsE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2023},"_npmUser":{"name":"omar.doist.com","email":"omar@doist.com"},"_npmVersion":"10.9.3","description":"OIDC trusted publishing setup package for @doist/piiranha","directories":{},"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/piiranha_0.0.1_1779324820646_0.9455767570185407","host":"s3://npm-registry-packages-npm-production"}},"3.5.8":{"name":"@doist/piiranha","version":"3.5.8","author":{"name":"Christian Theilemann","email":"christian@solvvy.com"},"license":"MIT","_id":"@doist/piiranha@3.5.8","maintainers":[{"name":"ricardoist","email":"ricardo@doist.com"},{"name":"henningmu","email":"muszynski.henning@gmail.com"},{"name":"jvalente","email":"joao@doist.com"},{"name":"antondoist","email":"antonball@doist.com"},{"name":"jefcurtis","email":"jef@doist.com"},{"name":"doistbot","email":"dev@doist.com"},{"name":"fbidu","email":"felipe@doist.com"},{"name":"goncalossilva","email":"goncalossilva@gmail.com"},{"name":"omar.doist.com","email":"omar@doist.com"},{"name":"itsevertv","email":"evert@doist.com"},{"name":"scottatdoist","email":"scott@doist.com"},{"name":"ernestodoist","email":"ernesto@doist.com"}],"homepage":"https://github.com/Doist/piiranha#readme","bugs":{"url":"https://github.com/Doist/piiranha/issues"},"dist":{"shasum":"abd61b373329480a28db4931f3818a3167825692","tarball":"https://registry.npmjs.org/@doist/piiranha/-/piiranha-3.5.8.tgz","fileCount":46,"integrity":"sha512-jBjh7r/WVpbPdzrDARMdtaMFJLGW6sHou+EDP/BwsaNSLpo/+xbr0NsCcXF8r2bB4/D9M0KqkF1+qDCU4hyE7g==","signatures":[{"sig":"MEYCIQDtA8dhGMUGr8FE5q1W/OlaVQcrn7J7W8jq9xV+chUs3AIhANXxymddf+mf1PvDDaxpLalSkvCZL/ljWlOXMNzmXop0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":355225},"main":"lib/index.js","gitHead":"656f61b5f0e16ba9d783f95f2d6ddf72423fd73f","scripts":{"test":"jest","build":"del lib && tsc --pretty","release":"npm whoami && git push --follow-tags && npm publish","prettier":"prettier './+(src|test)/**/*.+(js|ts|tsx)' --write","typecheck":"tsc --noEmit","verify_all":"npm run typecheck && npm test && npm run test_prettier","setup-hooks":"./scripts/setup-hooks.sh","release:patch":"npm whoami && npm version patch && git push --follow-tags && npm publish","test_prettier":"prettier './+(src|test)/**/*.+(js|ts|tsx)' --list-different","prepublishOnly":"npm run verify_all && npm run build"},"typings":"lib/index.d.ts","_npmUser":{"name":"omar.doist.com","email":"omar@doist.com"},"prettier":{"printWidth":120,"singleQuote":true},"repository":{"url":"git+https://github.com/Doist/piiranha.git","type":"git"},"_npmVersion":"10.9.3","description":"Remove personally identifiable information from text.","directories":{},"_nodeVersion":"22.19.0","dependencies":{"lodash":"^4.17.21"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"28.1.3","del-cli":"5.0.0","ts-jest":"28.0.7","prettier":"2.7.1","typescript":"4.7.4","@types/jest":"28.1.6","@types/lodash":"^4.17.24"},"_npmOperationalInternal":{"tmp":"tmp/piiranha_3.5.8_1779326620054_0.17143990104443474","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-05-21T00:53:40.546Z","modified":"2026-08-21T21:58:05.341Z","0.0.1":"2026-05-21T00:53:40.798Z","3.5.8":"2026-05-21T01:23:40.216Z"},"bugs":{"url":"https://github.com/Doist/piiranha/issues"},"author":{"name":"Christian Theilemann","email":"christian@solvvy.com"},"license":"MIT","homepage":"https://github.com/Doist/piiranha#readme","repository":{"url":"git+https://github.com/Doist/piiranha.git","type":"git"},"description":"Remove personally identifiable information from text.","maintainers":[{"email":"ricardo@doist.com","name":"ricardoist"},{"email":"muszynski.henning@gmail.com","name":"henningmu"},{"email":"joao@doist.com","name":"jvalente"},{"email":"antonball@doist.com","name":"antondoist"},{"email":"jef@doist.com","name":"jefcurtis"},{"email":"daw.gawel@gmail.com","name":"dmgawel"},{"email":"dev@doist.com","name":"doistbot"},{"email":"felipe@doist.com","name":"fbidu"},{"email":"goncalossilva@gmail.com","name":"goncalossilva"},{"email":"omar@doist.com","name":"omar.doist.com"},{"email":"scott@doist.com","name":"scottatdoist"},{"email":"craigcarlyle@me.com","name":"craigcarlyle"},{"email":"ernesto@doist.com","name":"ernestodoist"}],"readme":"# piiranha\n\n[![NPM Package](https://badge.fury.io/js/%40doist%2Fpiiranha.png)](https://www.npmjs.com/package/@doist/piiranha)\n\nRemove personally identifiable information from text.\n\n> This package is published on npm as [@doist/piiranha](https://www.npmjs.com/package/@doist/piiranha) and is maintained as a fork of the original [solvvy/redact-pii](https://github.com/solvvy/redact-pii) package.\n\n### Prerequisites\n\nThis library is primarily written for Node.js, but also works in the browser with compatible tooling/runtime (such as Vite, Webpack, Rollup, Parcel, esbuild). A transpiler/build setup such as TypeScript compiler, Babel, or both, can be used to target older browser support.\nIt is written in TypeScript and currently compiles to ES2016.\nThe project is tested in CI on Node.js 18.x and 20.x.\n\n### Simple example (synchronous API)\n\n```\nnpm install @doist/piiranha\n```\n\n```js\nimport { SyncRedactor } from 'piiranha';\nconst redactor = new SyncRedactor();\nconst redactedText = redactor.redact('Hi David Johnson, Please give me a call at 555-555-5555');\n// Hi NAME, Please give me a call at PHONE_NUMBER\nconsole.log(redactedText);\n```\n\nCommonJS equivalent:\n\n```js\nconst { SyncRedactor } = require('piiranha');\nconst redactor = new SyncRedactor();\nconst redactedText = redactor.redact('Hi David Johnson, Please give me a call at 555-555-5555');\n// Hi NAME, Please give me a call at PHONE_NUMBER\nconsole.log(redactedText);\n```\n\n### Simple example (asynchronous / promise-based API)\n\n```js\nimport { AsyncRedactor } from 'piiranha';\nconst redactor = new AsyncRedactor();\nredactor.redactAsync('Hi David Johnson, Please give me a call at 555-555-5555').then((redactedText) => {\n  // Hi NAME, Please give me a call at PHONE_NUMBER\n  console.log(redactedText);\n});\n```\n\n## Supported Features\n\n- sync and async API variants\n- ability to customize what to use as replacement value for detected patterns\n- built in regex based redaction rules for:\n  - credentials\n  - creditCardNumber\n  - emailAddress\n  - ipAddress\n  - names\n  - password\n  - phoneNumber\n  - streetAddress\n  - username\n  - usSocialSecurityNumber\n  - zipcode\n  - url\n  - digits\n- ability to add custom redaction regex patterns and complete custom redaction functions (both sync and async)\n\n## Advanced usage and features\n\n### Customize replacement values\n\n```js\nimport { SyncRedactor } from 'piiranha';\n\n// use a single replacement value for all built-in patterns found.\nconst redactor = new SyncRedactor({ globalReplaceWith: 'TOP_SECRET' });\nredactor.redact('Dear David Johnson, I live at 42 Wallaby Way');\n// Dear TOP_SECRET, I live at TOP_SECRET\n\n// use a custom replacement value for a specific built-in pattern\nconst redactor = new SyncRedactor({\n  builtInRedactors: {\n    names: {\n      replaceWith: 'ANONYMOUS_PERSON',\n    },\n  },\n});\n\nredactor.redact('Dear David Johnson');\n// Dear ANONYMOUS_PERSON\n```\n\n### Add custom patterns or redaction functions\n\nNote that the order of redaction rules matters, therefore you have to decide whether you want your custom redaction rules to run `before` or `after` the built-in ones. Generally it's better to put very specialized patterns or functions `before` the built-in ones and more broad / general ones `after`.\n\n```js\nimport { SyncRedactor } from 'piiranha';\n\n// add a custom regexp pattern\nconst redactor = new SyncRedactor({\n  customRedactors: {\n    before: [\n      {\n        regexpPattern: /\\b(cat|dog|cow)s?\\b/gi,\n        replaceWith: 'ANIMAL',\n      },\n    ],\n  },\n});\n\nredactor.redact('I love cats, dogs, and cows');\n// I love ANIMAL, ANIMAL, and ANIMAL\n\n// add a synchronous custom redaction function\nconst redactor = new SyncRedactor({\n  customRedactors: {\n    before: [\n      {\n        redact(textToRedact) {\n          return textToRedact.includes('TopSecret')\n            ? 'THIS_FILE_IS_SO_TOP_SECRET_WE_HAD_TO_REDACT_EVERYTHING'\n            : textToRedact;\n        },\n      },\n    ],\n  },\n});\n\nredactor.redact('This document is classified as TopSecret.');\n// THIS_FILE_IS_SO_TOP_SECRET_WE_HAD_TO_REDACT_EVERYTHING\n\nimport { AsyncRedactor } from './src/index';\n\n// add an asynchronous custom redaction function\nconst redactor = new AsyncRedactor({\n  customRedactors: {\n    before: [\n      {\n        redactAsync(textToRedact) {\n          return myCustomRESTApiServer.redactCustomWords(textToRedact);\n        },\n      },\n    ],\n  },\n});\n```\n\n### Disable specific built-in redaction rules\n\n```js\nconst redactor = new SyncRedactor({\n  builtInRedactors: {\n    names: {\n      enabled: false,\n    },\n    emailAddress: {\n      enabled: false,\n    },\n  },\n});\n```\n\n### Contributing\n\n#### Enable local git hooks\n\nTo block direct local commits to the `main` branch, run:\n\n```sh\nnpm run setup-hooks\n```\n\nThis configures `core.hooksPath` to use the committed hooks in `.githooks/`.\n\n#### Pull Request requirements\n\nBefore a PR can be merged to `main`:\n\n- **Code owner review** — A maintainer must approve the PR\n- **Passing tests** — All automated checks must pass:\n  - TypeScript type checking\n  - Jest unit tests (Node.js 18.x and 20.x)\n  - Prettier code formatting\n- **Stale reviews dismissed** — If you push new commits after approval, the review is dismissed and must be re-approved\n\nThese checks ensure code quality and prevent regressions.\n\n#### Branch naming convention\n\nFor non-main branches, commits are allowed only when branch names match:\n\n```text\n<owner>/<type>/<description>\n```\n\nAllowed `type` values:\n\n- feat\n- fix\n- chore\n- docs\n- refactor\n- test\n- ci\n- build\n- perf\n- style\n\nExamples:\n\n- `odsamuels/chore/setup-hooks`\n- `alice/feat/redaction-pipeline`\n\nAutomation branches are also allowed:\n\n- `dependabot/*`\n- `renovate/*`\n\n#### Run tests\n\nYou can run the tests via `npm run test`.\n","readmeFilename":"README.md"}