{"id":13847368,"url":"https://github.com/MichalZalecki/mappet","last_synced_at":"2025-07-12T08:31:39.847Z","repository":{"id":9270835,"uuid":"61454064","full_name":"MichalZalecki/mappet","owner":"MichalZalecki","description":"Lightweight, composable mappers for object transformations/normalization","archived":false,"fork":false,"pushed_at":"2023-01-03T15:16:37.000Z","size":1362,"stargazers_count":52,"open_issues_count":15,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-13T15:04:41.334Z","etag":null,"topics":["composable-mappers","transformations"],"latest_commit_sha":null,"homepage":"https://michalzalecki.github.io/mappet/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MichalZalecki.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-18T21:54:24.000Z","updated_at":"2024-07-22T16:05:31.000Z","dependencies_parsed_at":"2023-01-11T17:34:47.236Z","dependency_job_id":null,"html_url":"https://github.com/MichalZalecki/mappet","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/MichalZalecki/mappet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichalZalecki%2Fmappet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichalZalecki%2Fmappet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichalZalecki%2Fmappet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichalZalecki%2Fmappet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MichalZalecki","download_url":"https://codeload.github.com/MichalZalecki/mappet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MichalZalecki%2Fmappet/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264962250,"owners_count":23689769,"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":["composable-mappers","transformations"],"created_at":"2024-08-04T18:01:18.190Z","updated_at":"2025-07-12T08:31:39.580Z","avatar_url":"https://github.com/MichalZalecki.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# mappet\n\n[![CircleCI](https://circleci.com/gh/MichalZalecki/mappet.svg?style=svg)](https://circleci.com/gh/MichalZalecki/mappet)\n\nLightweight, composable mappers for object transformations/normalization.\n\n***\n[API Docs](https://michalzalecki.github.io/mappet) | [Examples](#examples)\n***\n\n## Installation ([npm](https://www.npmjs.com/package/mappet))\n\n```\nnpm i -S mappet\n```\n\n## Use cases\n\n* Fault tolerant object transformations, no more `Cannot read property of undefined`.\n* Normalizing API responses shape and key names e.g. to camelCase or flattening nested payloads\n* Preparing nested API request payloads from flat form data\n* Filtering object entries e.g. omitting entries with `undefined` value\n* Per field modifications e.g. `null` to empty string to make React inputs happy\n\n## Examples\n\n### Basic\n\nSimple value to value transformation\n\n```js\nconst schema = {\n  firstName: \"first_name\",\n  cardNumber: \"card.number\",\n};\nconst mapper = mappet(schema);\nconst source = {\n  first_name: \"Michal\",\n  last_name: \"Zalecki\",\n  card: {\n    number: \"5555-5555-5555-4444\",\n  },\n};\nconst result = mapper(source);\n// {\n//   firstName: \"Michal\",\n//   cardNumber: \"5555-5555-5555-4444\",\n// }\n```\n\n### Mapping values\n\nSchema entries can be also option objects of `path`, `modifier`, and `include`. Modifier accepts selected value and original source object.\n\n```js\nconst formatDate = (date, source) =\u003e moment(date).format(source.country === \"us\" ? \"MM/DD/YY\" : \"DD/MM/YY\");\nconst upperCase = v =\u003e v.toUpperCase();\n\nconst schema = {\n  country: { path: \"country\", modifier: upperCase },\n  date: { path: \"date\", modifier: formatDate },\n};\nconst mapper = mappet(schema);\nconst source = {\n  country: \"gb\",\n  date: \"2016-07-30\",\n};\nconst result = mapper(source);\n// {\n//   country: \"GB\",\n//   date: \"30/07/16\",\n// }\n```\n\n### Filtering entries\n\nUsing `include` you can control which values should be keept and what dropped.\n\n```js\nconst isGift = (value, source) =\u003e source.isGift;\n\nconst schema = {\n  quantity: [\"quantity\"],\n  message: { path: \"giftMessage\", include: isGift },\n  remind_before_renewing: { path: \"remindBeforeRenewingGift\", include: isGift },\n};\nconst mapper = mappet(schema);\nconst source = {\n  quantity: 3,\n  isGift: false,\n  giftMessage: \"All best!\",\n  remindBeforeRenewingGift: true,\n};\nconst result = mapper(source);\n// {\n//   quantity: 3,\n// };\n```\n\n### Composing mappers\n\nMappers are just closures. It's easy to combine them using modifiers.\n\n```js\nconst userSchema = {\n  firstName: \"first_name\",\n  lastName: \"last_name\",\n};\nconst userMapper = mappet(userSchema);\n\nconst usersSchema = {\n  totalCount: \"total_count\",\n  users: { path: \"items\", modifier: users =\u003e users.map(userMapper) },\n};\nconst usersMapper = mappet(usersSchema);\n\nconst source = {\n  total_count: 5,\n  items: [\n    { first_name: \"Michal\", last_name: \"Zalecki\" },\n    { first_name: \"John\", last_name: \"Doe\" },\n  ],\n};\nconst result = usersMapper(source);\n// {\n//   totalCount: 5,\n//   users: [\n//     { firstName: \"Michal\", lastName: \"Zalecki\" },\n//     { firstName: \"John\", lastName: \"Doe\" },\n//   ],\n// }\n```\n\n### Strict mode\n\nMappers in strict mode will throw exception when value is not found on source object.\n\n```js\nconst schema = {\n  firstName: \"first_name\",\n  lastName: \"last_name\",\n};\nconst mapper = mappet(schema, { strict: true });\nconst source = {\n  first_name: \"Michal\",\n};\nconst result = mapper(source);\n// Uncaught Mappet: last_name not found\n```\n\nYou can specify mapper name for easier debugging.\n\n```js\nconst userMapper = mappet(schema, { strictMode: true, name: \"User Mapper\" });\nconst user = mapper(source);\n// Uncaught User Mapper: last_name not found\n```\n\n### Greedy mode\n\nMappers in greedy mode will copy all properties from source object.\n\n```js\nconst schema = {\n  last_name: { path: \"last_name\", modifier: str =\u003e str.toUpperCase() },\n};\nconst mapper = mappet(schema, { greedy: true });\nconst source = {\n  first_name: \"Michal\",\n  last_name: \"Zalecki\",\n  email: \"example@michalzalecki.com\",\n};\nconst actual = mapper(source);\n// {\n//   first_name: \"Michal\",\n//   last_name: \"ZALECKI\",\n//   email: \"example@michalzalecki.com\",\n// }\n```\n\nSee [tests](src/mappet.spec.ts) for more examples.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMichalZalecki%2Fmappet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMichalZalecki%2Fmappet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMichalZalecki%2Fmappet/lists"}