{"id":28411621,"url":"https://github.com/matthewconstantine/normalized-get","last_synced_at":"2026-06-20T04:02:57.750Z","repository":{"id":66723159,"uuid":"86885114","full_name":"matthewconstantine/normalized-get","owner":"matthewconstantine","description":"Easily follow relationships in normalizr data","archived":false,"fork":false,"pushed_at":"2017-05-23T22:58:11.000Z","size":43,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-21T16:36:02.232Z","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/matthewconstantine.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2017-04-01T05:00:24.000Z","updated_at":"2018-11-06T04:03:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"f947ec41-c681-4e3c-998a-46d311b3c9e2","html_url":"https://github.com/matthewconstantine/normalized-get","commit_stats":{"total_commits":11,"total_committers":2,"mean_commits":5.5,"dds":"0.18181818181818177","last_synced_commit":"3a1a90e43a393f4b68b4f4f88cddbeb29e1d627c"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/matthewconstantine/normalized-get","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewconstantine%2Fnormalized-get","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewconstantine%2Fnormalized-get/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewconstantine%2Fnormalized-get/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewconstantine%2Fnormalized-get/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matthewconstantine","download_url":"https://codeload.github.com/matthewconstantine/normalized-get/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewconstantine%2Fnormalized-get/sbom","scorecard":{"id":626558,"data":{"date":"2025-08-11","repo":{"name":"github.com/matthewconstantine/normalized-get","commit":"3a1a90e43a393f4b68b4f4f88cddbeb29e1d627c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 1 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"58 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-832h-xg76-4gv6","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-9vvw-cc9w-f27h","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-hr2v-3952-633q","Warn: Project is vulnerable to: GHSA-h6ch-v84p-w6p9","Warn: Project is vulnerable to: GHSA-4gmj-3p3h-gm8h","Warn: Project is vulnerable to: GHSA-qrmc-fj45-qfc2","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-xf7w-r453-m56c","Warn: Project is vulnerable to: GHSA-qh2h-chj9-jffq","Warn: Project is vulnerable to: GHSA-44pw-h2cw-w3vq","Warn: Project is vulnerable to: GHSA-jp4x-w63m-7wgm","Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-4hpf-3wq7-5rpr","Warn: Project is vulnerable to: GHSA-f522-ffg8-j8r6","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-282f-qqgm-c34q","Warn: Project is vulnerable to: GHSA-fvqr-27wr-82fm","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-5947-m4fg-xhqg","Warn: Project is vulnerable to: GHSA-779f-wgxg-qr8f","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w9mr-4mfr-499f","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-6g33-f262-xjp4","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-2m39-62fm-q8r3","Warn: Project is vulnerable to: GHSA-mf6x-7mm4-x2g7","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-g7q5-pjjr-gqvp","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T06:39:27.514Z","repository_id":66723159,"created_at":"2025-08-21T06:39:27.515Z","updated_at":"2025-08-21T06:39:27.515Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34556495,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":"2025-06-02T18:17:03.704Z","updated_at":"2026-06-20T04:02:57.724Z","avatar_url":"https://github.com/matthewconstantine.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Normalized Get\n\nHelper functions for traversing [normalizr](https://github.com/paularmstrong/normalizr) relationships.\n\n## Who is this for?\n\nAnyone that uses [normalizr](https://github.com/paularmstrong/normalizr), or normalized data that conforms to it.\n\n## What does it do?\n\n1. `NormalizedGet` lets you access normalized data using a path as though it was denormalized. \n2. `GraphGet` lets you denormalize multiple paths at once, perfect for using in components.\n\n### NormalizedGet\n\nSay you have a schema like this:\n```js\n  const users = new schema.Entity('users');\n  const comments = new schema.Entity('comments', {\n    user: users\n  });\n  const articles = new schema.Entity('articles', {\n    author: users,\n    comments: [comments]\n  });\n  return { comments, articles, users };\n```\n\nJust setup `bindNoramlizedGet` like so:\n```js\nconst normalizedGet = bindNormalizedGet(schemas, data); \n```\n\nNow you can access deep relationships with a single line of code:\n\n```js\n// With normalizedGet\nconst commenters = normalizedGet('articles[123].comments.user');\n```\n\nIt even follows Array entities. So the above example will map over the comments and return the authors.\n\nFor comparison, here's how you'd do it without `normalizedGet`:\n```js\n// Without normlaizedGet:\nconst commenters = Object.keys(data.comments)\n  .map(key =\u003e {\n    const userId = data.comments[key].user\n    return data.users[userId];\n  });\n```\n\nThe more relationships your data has have the more complex this manual fetching gets. And you have to remember which property maps to which model.\n\n### graphGet\n\n`normalizedGet` is nice for getting a specific piece of data from your entity graph. What if you need more data? That's where `graphGet` comes in handy. It returns a deep structure containing the data you specify.\n\nFirst we bind `graphGet` using the similar config method as before:\n```js\nconst graphGet = bindGraphGet(schemas, data); \n```\n\nNow we can retrieve the commenters as before, but also the article and comments too.\n```js\nconst models = graphGet('articles[123].comments.user')\n```\n\nThis will output nested data ready for use in a view:\n```js\n{\n  articles: {\n    123: {\n      title: '…',\n      comments: [{\n        comment: 'Looks good to me', \n        user: { name: 'Jane' } \n      }, {…}, {…}]\n    }\n  }\n}\n```\n\n`GraphGet` can accept multiple paths and merge them together.\n```js\ngraphGet(\n  `articles[${articleId}].comments.user`,\n  `users[${currentUserId}]`\n)\n```\n\n## Differences between graphGet and normalizedGet\nBoth functions use the same underlying recursive getter. Both map over array results. `normalizedGet` only returns the \"leaf\" data, the last element of the path. `graphGet` returns both the leaf and the data leading to it. `normalizedGet` works only on a single path and has no merge strategy. `graphGet` merges paths into an identity map at the root.\n\n## Usage\n\nFirst bind your schemas. This makes it easy to use the getters without passing schemas and data in each time. Probably best to do this somewhere central in your project and export the bound getter.\n\n```js\nexport const normalizedGet = bindNormalizedGet(schemas, data);\nexport const graphGet = bindGraphGet(schemas, data);\n```\n\nNow you have `normalizedGet` and `graphGet` functions ready for easy data denormalization.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewconstantine%2Fnormalized-get","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatthewconstantine%2Fnormalized-get","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewconstantine%2Fnormalized-get/lists"}