{"id":41003863,"url":"https://github.com/ecamp/hal-json-vuex","last_synced_at":"2026-01-22T08:36:57.247Z","repository":{"id":37206490,"uuid":"311104086","full_name":"ecamp/hal-json-vuex","owner":"ecamp","description":"Use a HAL JSON API with a Vuex store.","archived":false,"fork":false,"pushed_at":"2025-12-31T16:11:39.000Z","size":3235,"stargazers_count":8,"open_issues_count":30,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2026-01-05T01:02:50.391Z","etag":null,"topics":["axios","hacktoberfest","vue"],"latest_commit_sha":null,"homepage":"","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/ecamp.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-11-08T16:22:44.000Z","updated_at":"2025-02-14T03:25:07.000Z","dependencies_parsed_at":"2026-01-01T02:08:35.740Z","dependency_job_id":null,"html_url":"https://github.com/ecamp/hal-json-vuex","commit_stats":{"total_commits":278,"total_committers":6,"mean_commits":"46.333333333333336","dds":"0.19784172661870503","last_synced_commit":"e4d893b7427595fe907e83f993ffe911c9cb8384"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/ecamp/hal-json-vuex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecamp%2Fhal-json-vuex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecamp%2Fhal-json-vuex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecamp%2Fhal-json-vuex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecamp%2Fhal-json-vuex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ecamp","download_url":"https://codeload.github.com/ecamp/hal-json-vuex/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecamp%2Fhal-json-vuex/sbom","scorecard":{"id":364924,"data":{"date":"2025-08-11","repo":{"name":"github.com/ecamp/hal-json-vuex","commit":"694c2fa2b86cdf6414517cf4c1482c02c0a0c309"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/29 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":"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/continuous-integration.yml:1","Info: no jobLevel write permissions found"],"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":"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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"Pinned-Dependencies","score":2,"reason":"dependency not pinned by hash detected -- score normalized to 2","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/continuous-integration.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/ecamp/hal-json-vuex/continuous-integration.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/continuous-integration.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/ecamp/hal-json-vuex/continuous-integration.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/continuous-integration.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/ecamp/hal-json-vuex/continuous-integration.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/continuous-integration.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/ecamp/hal-json-vuex/continuous-integration.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/continuous-integration.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/ecamp/hal-json-vuex/continuous-integration.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/continuous-integration.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/ecamp/hal-json-vuex/continuous-integration.yml/master?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   2 out of   2 npmCommand dependencies pinned"],"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":"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":"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":"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":"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":"25 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-jr5f-v2jv-69x6","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-5j4c-8p2g-v4jx","Warn: Project is vulnerable to: GHSA-g3ch-rx76-35fx","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh"],"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-18T11:38:52.595Z","repository_id":37206490,"created_at":"2025-08-18T11:38:52.595Z","updated_at":"2025-08-18T11:38:52.595Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28659518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"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":["axios","hacktoberfest","vue"],"created_at":"2026-01-22T08:36:57.165Z","updated_at":"2026-01-22T08:36:57.228Z","avatar_url":"https://github.com/ecamp.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hal-json-vuex\n\n[![npm version](https://img.shields.io/npm/v/hal-json-vuex.svg?style=flat)](https://www.npmjs.com/package/hal-json-vuex)\n[![Downloads](http://img.shields.io/npm/dm/hal-json-vuex.svg?style=flat-square)](https://npmjs.org/package/hal-json-vuex)\n[![Build Status](https://travis-ci.com/ecamp/hal-json-vuex.svg?branch=master)](https://travis-ci.com/ecamp/hal-json-vuex)\n[![Coverage Status](https://coveralls.io/repos/github/ecamp/hal-json-vuex/badge.svg?branch=master)](https://coveralls.io/github/ecamp/hal-json-vuex?branch=master)\n\nA package to access [HAL JSON](https://tools.ietf.org/html/draft-kelly-json-hal-08) data from an API, using a [Vuex](https://vuex.vuejs.org) store, restructured to make life easier.\n\nWith this plugin, you can use your HAL JSON API in a fluid way:\n```js\n// Reading data and traversing relationships\nlet singleBook = this.api.get('/books/1')\nlet firstBookName = this.api.get().books().items[0].name // visits the 'books' rel on the root API endpoint\nlet author = singleBook.author() // related entity\nlet bookChapters = this.api().books().items[0].chapters()\nauthor = singleBook.author() // doesn't trigger another network call because we already fetched it\nthis.api.reload(author) // force re-fetching an entity or a URI\n\n// Writing data\nthis.api.post('/books', { name: 'My first book', author: { _links: { self: '/users/433' } } })\nthis.api.patch(singleBook, { name: 'Single book - volume 2' })\nthis.api.del(author).then(() =\u003e { /* do something */ })\n```\n\nThis library will only load data from the API when necessary (i.e. if the data is not yet in the Vuex store).\nIt also supports templated links and partially loaded data from the API.\n\n# Installation\n\n```bash\nnpm install hal-json-vuex\n```\n\n# Usage\n\n```js\nimport Vue from 'vue'\nimport Vuex from 'vuex'\nimport axios from 'axios'\nimport HalJsonVuex from 'hal-json-vuex'\n\nVue.use(Vuex)\n\nconst store = new Vuex.Store({})\n\naxios.defaults.baseURL = 'https://my-api.com/api'\n\nVue.use(HalJsonVuex(store, axios, { /* options */ }))\n```\n\n```js\n// Use it in a computed or method or lifecycle hook of a Vue component\nlet someEntity = this.api.get('/some/endpoint')\nthis.api.reload(someEntity)\n```\n\n```html\n\u003c!-- Use it in the \u003ctemplate\u003e part of a Vue component --\u003e\n\u003cli v-for=\"book in api.get('/all/my/books').items\" :key=\"book._meta.self\"\u003e...\u003c/li\u003e\n```\n\n### Nuxt.js (experimental support)\nTo install in a Nuxt.js application:\n```js\n// First, make sure the Nuxt.js app uses Vuex, by adding an index.js to your store/ directory.\n\n// Then, create a file plugins/hal-json-vuex.js with the following content:\nimport Vue from 'vue'\nimport HalJsonVuex from 'hal-json-vuex'\n\nexport default function ({ store, $axios }, nuxtInject) {\n  if (!Vue.$api) {\n    Vue.use(HalJsonVuex(store, $axios, { nuxtInject }))\n  }\n}\n\n// Add the plugin to nuxt.config.js:\nexport default {\n  plugins: [\n    { src: '~/plugins/hal-json-vuex.js' }\n  ],\n  // ...\n}\n```\nThen, you can use `$api` on both the server side and the client side:\n```js\n// On the server\nasync asyncData({ $api }) {\n  const books = await $api.get().books()._meta.load\n  return { books }\n}\n```\n\n```js\n// On the client, in a computed or method or lifecycle hook of a Vue component\nlet someEntity = this.$api.get('/some/endpoint')\n```\n\n```html\n\u003c!-- On the client, in the \u003ctemplate\u003e part of a Vue component --\u003e\n\u003cli v-for=\"book in $api.get('/all/my/books').items\" :key=\"book._meta.self\"\u003e...\u003c/li\u003e\n```\n\n# Available options\n\n### apiName\nThis package will install a module into your Vuex store, as well as an accessor (`this.api`) into your Vue prototype.\nThese are by default called `api`, but in case you want to change that or need to support multiple APIs at the same time, you can use the `apiName` option:\n```js\nVue.use(HalJsonVuex(store, axios, { apiName: 'backend' }))\n\n// In a Vue component\nlet someEntity = this.backend.get('/some/endpoint')\n```\n\n### avoidNPlusOneRequests\nWhen accessing the elements of an embedded collection, and some of the elements of the collection have not been loaded from the API before, this library will automatically try to avoid N+1 queries by eager fetching the whole collection.\nIn case you run into problems with this behaviour with your API, you can disable it by setting the `avoidNPlusOneRequests` option to false:\n```js\nVue.use(HalJsonVuex(store, axios, { avoidNPlusOneRequests: false }))\n```\n\n### forceRequestedSelfLink\nWhen requesting an entity, some HAL JSON APIs will not always return the same `self` link as it was in the request.\nAn example would be if the API added a `page=0` query parameter to the `self` link of a collection, even if the request was done without that parameter:\n```\n// request\nGET /all/my/books\n\n// response JSON from the API\n{\n  \"_embedded\": {\n    \"items\": [ ... ]\n  },\n  \"_links\": {\n    \"self\": {\n      \"href\": \"/all/my/books?page=0\"\n    }\n  }\n}\n```\nThis can lead to problems, because in your component template you might be requesting `/all/my/books` but that URI never appears in your Vuex store, causing an infinite loop of re-fetching the same URI.\n\nIn case your backend API does this, you can set the `forceRequestedSelfLink` option to true, and the top-level `self` link in all responses will be overwritten to the link that was actually requested.\n```js\nVue.use(HalJsonVuex(store, axios, { forceRequestedSelfLink: true }))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecamp%2Fhal-json-vuex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fecamp%2Fhal-json-vuex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecamp%2Fhal-json-vuex/lists"}