{"id":22096511,"url":"https://github.com/uphold/anonymizer","last_synced_at":"2025-07-24T22:32:09.469Z","repository":{"id":40732237,"uuid":"200922380","full_name":"uphold/anonymizer","owner":"uphold","description":null,"archived":false,"fork":false,"pushed_at":"2024-11-07T09:40:12.000Z","size":762,"stargazers_count":1,"open_issues_count":9,"forks_count":2,"subscribers_count":46,"default_branch":"master","last_synced_at":"2024-11-07T10:34:32.498Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uphold.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-06T20:47:13.000Z","updated_at":"2024-11-07T09:40:14.000Z","dependencies_parsed_at":"2023-12-12T19:41:46.539Z","dependency_job_id":"d90afcc5-0ad0-4a53-9e55-c4370afdfecc","html_url":"https://github.com/uphold/anonymizer","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Fanonymizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Fanonymizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Fanonymizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uphold%2Fanonymizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uphold","download_url":"https://codeload.github.com/uphold/anonymizer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227482485,"owners_count":17779968,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-01T04:11:21.526Z","updated_at":"2025-07-24T22:32:09.450Z","avatar_url":"https://github.com/uphold.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# anonymizer\n\nObject redaction library that supports whitelisting, blacklisting and wildcard matching.\n\n## Installation\n\n```bash\nnpm install @uphold/anonymizer\n```\n\n## Usage\n\n### Basic example\n\n```js\nimport { anonymizer } from '@uphold/anonymizer';\n\nconst whitelist = ['key1', 'key2.foo'];\nconst anonymize = anonymizer({ whitelist });\n\nconst data = {\n  key1: 'bar',\n  key2: {\n    foo: 'bar',\n    bar: 'baz',\n    baz: {\n      foo: 'bar',\n      bar: 'baz'\n    }\n  }\n};\n\nanonymize(data);\n\n// {\n//   key1: 'bar',\n//   key2: {\n//     foo: 'bar',\n//     bar: '--REDACTED--',\n//     baz: {\n//       foo: '--REDACTED--'\n//       bar: '--REDACTED--'\n//     }\n//   }\n// }\n```\n\n### Wildcard matching example\n\nUsing `*` allows you to match any character in a key, except for `.`.\nThis is similar to how `glob` allows you to use `*` to match any character, except for `/`.\n\n```js\nimport { anonymizer } from '@uphold/anonymizer';\n\nconst whitelist = ['key2.*'];\nconst anonymize = anonymizer({ whitelist });\n\nconst data = {\n  key1: 'bar',\n  key2: {\n    foo: 'bar',\n    bar: 'baz',\n    baz: {\n      foo: 'bar',\n      bar: 'baz'\n    }\n  }\n};\n\nanonymize(data);\n\n// {\n//   key1: '--REDACTED--',\n//   key2: {\n//     foo: 'bar',\n//     bar: 'baz',\n//     baz: {\n//       foo: '--REDACTED--',\n//       bar: '--REDACTED--'\n//     }\n//   }\n// }\n```\n\n### Double wildcard matching example\n\nUsing `**` allows you to match any nested key.\nThis is similar to how `glob` allows you to use `**` to match any nested directory.\n\n```js\nimport { anonymizer } from '@uphold/anonymizer';\n\nconst whitelist = ['key2.**', '**.baz'];\nconst blacklist = ['key2.bar']\nconst anonymize = anonymizer({ blacklist, whitelist });\n\nconst data = {\n  key1: 'bar',\n  key2: {\n    foo: 'bar',\n    bar: 'baz',\n    baz: {\n      foo: 'bar',\n      bar: 'baz'\n    }\n  },\n  key3: {\n    foo: {\n      baz: 'biz'\n    }\n  }\n};\n\nanonymize(data);\n\n// {\n//   key1: '--REDACTED--',\n//   key2: {\n//     foo: 'bar',\n//     bar: '--REDACTED--',\n//     baz: {\n//       foo: 'bar',\n//       bar: 'baz'\n//     }\n//   },\n//   key3: {\n//     foo: {\n//       baz: 'biz'\n//     }\n//   }\n// }\n```\n\n### Custom replacement example\n\nBy default, the replacement value is `--REDACTED--`. You can customize it by passing a `replacement` function in the options.\n\nHere's an example that keeps strings partially redacted:\n\n```js\nimport { anonymizer } from '@uphold/anonymizer';\n\nconst replacement = (key, value, path) =\u003e {\n  if (typeof value !== 'string') {\n    return '--REDACTED--';\n  }\n\n  // Keep the first half of the string and redact the rest.\n  const charsToKeep = Math.floor(value.length / 2);\n\n  return value.substring(0, charsToKeep) + '*'.repeat(Math.min(value.length - charsToKeep, 100));\n};\n\nconst anonymize = anonymizer({}, { replacement });\n\nconst data = {\n  key1: 'bar',\n  key2: {\n    foo: 'bar',\n    bar: 'baz',\n    baz: {\n      foo: 'bar',\n      bar: 'baz'\n    }\n  }\n};\n\nanonymize(data);\n\n// {\n//   key1: 'b**',\n//   key2: {\n//     foo: 'b**'\n//     bar: 'b**',\n//     baz: {\n//       foo: 'b**',\n//       bar: 'b**'\n//     },\n//   }\n// }\n```\n\n### Trim redacted values to keep output shorter\n\nIn certain scenarios, you may want to trim redacted values to keep the output shorter. Such example is if you are redacting logs and sending them to a provider, which may charge you based on the amount of data sent and stored.\n\nThis can be achieved by setting the `trim` option to `true`, like so:\n\n```js\nconst whitelist = ['key1', 'key2.foo'];\nconst anonymize = anonymizer({ whitelist }, { trim: true });\n\nconst data = {\n  key1: 'bar',\n  key2: {\n    foo: 'bar',\n    bar: 'baz',\n    baz: {\n      foo: 'bar',\n      bar: 'baz'\n    }\n  }\n};\n\nanonymize(data);\n\n// {\n//   __redacted__: [ 'key2.bar', 'key2.baz.foo', 'key2.baz.bar']\n//   key1: 'bar',\n//   key2: {\n//     foo: 'bar'\n//   }\n// }\n```\n\n### Serializers example\n\nSerializers allow you to apply custom transformations to specific values before being redacted.\n\nHere's an example:\n\n```js\nconst { anonymizer } = require('@uphold/anonymizer');\nconst whitelist = ['foo.key'];\nconst serializers = [\n  { path: 'foo.key', serializer: () =\u003e 'biz' },\n]\nconst anonymize = anonymizer({ whitelist }, { serializers });\n\nconst data = {\n  foo: { key: 'public' },\n};\n\nanonymize(data);\n\n// {\n//   foo: {\n//     key: 'biz'\n//   }\n// }\n```\n\nTake a look at the [built-in serializers](#serializers) for common use cases.\n\n## API\n\n### anonymizer({ whitelist, blacklist }, options)\n\nReturns a function that redacts a given object based on the provided whitelist and blacklist.\n\n#### whitelist\n\nType: `Array`  \nDefault: `[]`\n\nAn array of whitelisted patterns to use when matching against object paths that should not be redacted.\n\n#### blacklist\n\nType: `Array`  \nDefault: `[]`\n\nAn array of blacklisted patterns to use when matching against object paths that should be redacted.\n\nBy default, every value is redacted. However, the blacklist can be used in conjunction with a whitelist. The values that match the blacklist will be redacted, even if they match the whitelist.\n\n#### options\n\n##### options.replacement\n\nType: `Function`  \nDefault: `(key, value, path) =\u003e '--REDACTED--'`\n\nA function that allows customizing the replacement value (default implementation is `--REDACTED--`).\n\nIt receives the following arguments: `key` _(String)_, `value` _(Any)_, and `path` _(String)_.\n\n##### options.serializers\n\nType: `Array`  \nDefault: `[]`\n\nA list with serializers to apply. Each serializers must contain two properties: `path` (path for the value to be serialized, must be a `string`) and `serializer` (function to be called on the path's value).\n\n##### options.trim\n\nType: `Boolean`  \nDefault: `false`\n\nA flag that enables trimming all redacted values, saving their keys to a `__redacted__` list. Please note that trimming is only applied when the replacement value is `--REDACTED--`.\n\n### serializers\n\nBuilt-in serializer functions you may use in the `serializers` option.\n\n#### error\n\nSerializes an `Error` object.\n\n#### datadogError\n\nSerializes an `Error` object for the purpose of sending it to Datadog, adding a `kind` property based on the error class name.\n\n## Release process\n\nThe release of a version is automated via the [release](https://github.com/uphold/anonymizer/.github/workflows/release.yml) GitHub workflow. Run it by clicking the \"Run workflow\" button.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuphold%2Fanonymizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuphold%2Fanonymizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuphold%2Fanonymizer/lists"}