{"_rev":"12-b61af119fd0dddb9a927fe76b6cf49c8","time":{"created":"2023-04-16T20:32:26.200Z","2.2.2":"2023-04-16T07:11:07.185Z","modified":"2023-04-16T20:32:26.746Z","2.2.3":"2023-04-16T07:29:43.536Z","2.2.4":"2023-04-16T19:50:58.490Z","2.2.5":"2023-04-16T20:15:38.318Z","2.2.6":"2023-04-16T20:17:14.117Z","2.2.7":"2023-04-16T20:19:39.333Z","2.2.8":"2023-04-16T20:20:28.024Z","2.2.9":"2023-04-16T20:21:09.272Z","2.2.10":"2023-04-16T20:23:00.124Z","2.3.0":"2023-04-16T20:27:16.874Z","2.2.20":"2023-04-16T20:32:26.575Z"},"_id":"@clabnet/vue-simple-acl","name":"@clabnet/vue-simple-acl","dist-tags":{"latest":"2.2.20"},"versions":{"2.2.20":{"name":"@clabnet/vue-simple-acl","version":"2.2.20","description":"A simple unopinionated Vue plugin for managing user roles and permissions, access-control list (ACL) and role-based access control (RBAC).","license":"MIT","author":{"name":"Victory Osayi","email":"lavictorybiz@gmail.com"},"contributors":[{"name":"Claudio Barca","email":"c.barca@libero.it","url":"https://github.com/clabnet"}],"exports":{".":{"import":"./dist/index.js","require":"./dist/index.mjs","types":"./dist/index.d.ts"}},"keywords":["vue","vuejs","vue2","vue 2","vue3","vue 3","acl","rbac","vue-simple-acl","Access-Control List","Role Based Access Control","typescript"],"main":"./dist/index.js","module":"./dist/index.mjs","typings":"./dist/index.d.ts","scripts":{"xxxdev":"vite","dev":"tsup --watch","build":"tsup","build:vite":"tsc && vite build","lint":"eslint src --ext .ts","prettier":"prettier --write .","preview":"vite preview","test:coverage":"vitest run --coverage","test:run":"vitest run","test:watch":"vitest","pack":"pnpm build && cd ./dist && npm pack","publish":"npm publish --access public"},"devDependencies":{"@rollup/plugin-typescript":"^11.1.0","@types/luxon":"^3.3.0","@types/node":"^18.15.11","@vitest/coverage-c8":"^0.30.1","c8":"^7.13.0","picocolors":"^1.0.0","prettier":"^2.8.7","rollup-plugin-typescript-paths":"^1.4.0","tslib":"^2.5.0","tsup":"^6.7.0","typescript":"^5.0.4","vite":"^4.2.1","vite-plugin-progress":"^0.0.7","vitest":"^0.30.1","@typescript-eslint/eslint-plugin":"^5.58.0","@typescript-eslint/parser":"^5.58.0","@vitejs/plugin-vue":"^4.1.0","@vue/compiler-sfc":"^3.2.47","@vuedx/typecheck":"^0.7.6","@vuedx/typescript-plugin-vue":"^0.7.6","axios":"^1.3.5","cross-env":"^7.0.3","eslint":"^8.38.0","eslint-plugin-vue":"^9.11.0","vue":"^3.2.47","vue-router":"^4.1.6"},"repository":{"type":"git","url":"git+https://github.com/clabnet/vue-simple-acl.git"},"bugs":{"url":"https://github.com/clabnet/vue-simple-acl/issues"},"homepage":"https://github.com/clabnet/vue-simple-acl#readme","gitHead":"8e39b293eba59a765d955e524eab1406e5792c04","_id":"@clabnet/vue-simple-acl@2.2.20","_nodeVersion":"18.12.0","_npmVersion":"9.3.0","dist":{"integrity":"sha512-n1rvHyIpvQsTV+Zmq/B7b7ugLQhmRwy6ccQnMBZPmHXMUET95V7hGodaCbWqL9ToRAvz47gPbrt/oVgp+EjhAw==","shasum":"4762adb5e381509474c1ec6193ba1131a3eea265","tarball":"https://registry.npmjs.org/@clabnet/vue-simple-acl/-/vue-simple-acl-2.2.20.tgz","fileCount":19,"unpackedSize":1065265,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBhN74MzhfcUGnTnYnR7tSstNc0XRFHwjVRpDrjvQh21AiEA1td2UBE+EhBRyE7dGRFfHm4AHsdgG5zNzC+2aFkMVck="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPFtaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr+DA//Xerp1fHIdKzUGvew0Nfug1MhEVTl/euqVyKJEy73fJDsQDca\r\nwpRuNdKuQSX7bfwqHA/UWU6GCTBxPySFk3X+wg0DPUp08YtezJ1t5f94qRT8\r\n7cEFnT43+PMtthB8utfL9GDV+5j1AZe1sF3tnCxIBTmr3mI7ttcz3zwDlaaw\r\nXvS7rASKQk/otxyUn7Fgc7O0t1V1dP7FIGc+eXBTqXck9/emiztAZCs1qBoL\r\nLCE14QyH16s5TNL8XdHi8+z2otaz/GjYtErI+KbqwhBxSPZ3sG4EmF970qcw\r\n8N98UUMy8UMSqDIcZYZvp/UUK6SezZElPi9OtFVdXzgrweEVmTNQHDCnBRg5\r\n6aaji9INCySO86da00TGZv1rLN5nTlu9b008E4KPDz3O0fWt0K+CPgHXA4A3\r\n4nnuR/4kI6+myKQ/J8K8JHMFG8YbfF+k7XvsG5yN+QjmFN3fv8uQvefd5FW+\r\nZimX9sPNGhPfRwhXHW31qbcsfwEh6Rl9noVHA9rbG43qSdyKQqcWzxIqcom4\r\n6hWcxKwSNM83Y2MF/82i9ClgKP3b8KykaixSRgZAmOXROOEOwUL2YjNNF1k6\r\nFhsXX1oot5Lmy2mW71Wr5ANCQGV2lzZq/EIDBUwZ5qTHKICIaKuH4RcPxieN\r\ncx3JdUXddv7e6yUPZC62LfS+nWH32o0I+qY=\r\n=+AEH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"clabnet","email":"c.barca@libero.it"},"directories":{},"maintainers":[{"name":"clabnet","email":"c.barca@libero.it"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/vue-simple-acl_2.2.20_1681677146266_0.9180975450283833"},"_hasShrinkwrap":false}},"maintainers":[{"name":"clabnet","email":"c.barca@libero.it"}],"description":"A simple unopinionated Vue plugin for managing user roles and permissions, access-control list (ACL) and role-based access control (RBAC).","homepage":"https://github.com/clabnet/vue-simple-acl#readme","keywords":["vue","vuejs","vue2","vue 2","vue3","vue 3","acl","rbac","vue-simple-acl","Access-Control List","Role Based Access Control","typescript"],"repository":{"type":"git","url":"git+https://github.com/clabnet/vue-simple-acl.git"},"contributors":[{"name":"Claudio Barca","email":"c.barca@libero.it","url":"https://github.com/clabnet"}],"author":{"name":"Victory Osayi","email":"lavictorybiz@gmail.com"},"bugs":{"url":"https://github.com/clabnet/vue-simple-acl/issues"},"license":"MIT","readme":"# Vue Simple ACL\n\nA simple unopinionated Vue plugin for managing user roles and permissions, access-control list (ACL) and role-based access control (RBAC).\n\n<div align=\"center\">\n\n  <a href=\"https://www.npmjs.com/package/vue-simple-acl\" target=\"_blank\">\n    <img src=\"https://img.shields.io/npm/v/vue-simple-acl.svg\" alt=\"Version\">\n  </a>\n  <a href=\"https://vuejs.org/\" target=\"_blank\"><img src=\"https://badgen.net/badge/Vue/2.x/cyan\" alt=\"Vue 2\"></a>\n  <a href=\"https://v3.vuejs.org/\" target=\"_blank\"><img src=\"https://badgen.net/badge/Vue/3.x/cyan\" alt=\"Vue 3\"></a>\n  <a href=\"https://www.npmjs.com/package/vue-simple-acl\" target=\"_blank\">\n    <img alt=\"NPM Total Downloads\" src=\"https://img.shields.io/npm/dt/vue-simple-acl?color=%2353ca2f\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/vue-simple-acl\" target=\"_blank\">\n    <img alt=\"NPM Monthly Downloads\" src=\"https://img.shields.io/npm/dm/vue-simple-acl?color=%2353ca2f\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/vue-simple-acl\" target=\"_blank\">\n    <img alt=\"NPM bundle size (scoped version)\" src=\"https://img.shields.io/bundlephobia/minzip/vue-simple-acl?color=53ca2f\">\n  </a>\n  <a href=\"LICENSE\" target=\"_blank\"><img src=\"https://img.shields.io/npm/l/vue-gates.svg\" alt=\"License\"></a>\n\n</div>\n\n## Table of Contents\n- [Vue Simple ACL](#vue-simple-acl)\n  - [Table of Contents](#table-of-contents)\n  - [Features](#features)\n  - [Installation](#installation)\n      - [NPM](#npm)\n      - [Yarn](#yarn)\n      - [CDN](#cdn)\n  - [Usage](#usage)\n    - [Usage with Vue 3](#usage-with-vue-3)\n    - [Usage with Vue 2](#usage-with-vue-2)\n    - [ACL Rules File](#acl-rules-file)\n    - [Usage in component](#usage-in-component)\n      - [`hide` modifier](#hide-modifier)\n      - [`disable` modifier](#disable-modifier)\n      - [`readonly` modifier](#readonly-modifier)\n      - [`not` modifier](#not-modifier)\n      - [`any` modifier](#any-modifier)\n    - [Using helper function in component](#using-helper-function-in-component)\n    - [Using helper function in `setup` Vue's Composition API](#using-helper-function-in-setup-vues-composition-api)\n    - [Middleware for Vue Router](#middleware-for-vue-router)\n      - [`onDeniedRoute` meta property](#ondeniedroute-meta-property)\n      - [$from as value `onDeniedRoute`](#from-as-value-ondeniedroute)\n    - [Vue Router `meta` Properties](#vue-router-meta-properties)\n  - [Semantic Alias directives and methods](#semantic-alias-directives-and-methods)\n  - [Vue Simple ACL Options](#vue-simple-acl-options)\n  - [TODO](#todo)\n  - [🤝 Contributing](#-contributing)\n  - [⭐️ Support](#️-support)\n  - [📄 License](#-license)\n\n\n<br>\n\n<a name=\"features\"></a>\n\n## Features\n- Vue 2 and Vue 3 support\n- Simple but robust and power ACL plugin\n- Manage roles and permissions with ease.\n- Lightweight (<3 kB zipped)\n- Component `v-can` directive\n- Global `$can` helper function\n- Sematic alias methods and directives of different verb for directive and helper function. E.g `v-role`, `v-permission`, `$acl.permission()`, `$acl.anyRole()`, etc.\n- Middleware support for [Vue Router](https://next.router.vuejs.org/) through `meta` property.\n- Support user data from plain object, pinia/vuex store and asynchronous function.\n- Reactive changes of abilities and permissions\n- Define custom ACL rules\n- Fully Typecript: The source code is written entirely in TypeScript.\n- Fully configurable\n\n<a name=\"installation\"></a>\n\n## Installation\n#### NPM\n```\nnpm install vue-simple-acl\n```\n#### Yarn\n```\nyarn add vue-simple-acl\n```\n#### CDN\n[UNPKG](https://unpkg.com/vue-simple-acl)\n[JSDelivr](https://cdn.jsdelivr.net/npm/vue-simple-acl@latest/dist/vue-simple-acl.js)\n\n\n<a name=\"usage\"></a>\n\n## Usage\n\n<a name=\"usage-vue3\"></a>\n\n### Usage with Vue 3\n```javascript\n// src/main.js  OR  src/main.ts\n\nimport { createApp } from 'vue'\nimport App from './App.vue'\nimport router from './store';\nimport store from './store';\nimport acl from './acl'; // import the instance of the defined ACL\n\nconst app = createApp(App);\napp.use(router);\napp.use(store);\napp.use(acl); // install vue-simple-acl\napp.mount(\"#app\");\n```\n\n<a name=\"usage-vue2\"></a>\n\n### Usage with Vue 2\nIn Vue 2, when using User data from reactive Store/Pinia/Vuex wrapped with `computed()` function, which is available in Vue 3 as module by default but not in Vue 2, make sure to install [@vue/composition-api](https://github.com/vuejs/composition-api#npm) first and change the imported module to: `import { computed } from '@vue/composition-api'`\n```javascript\n// src/main.js  OR  src/main.ts\n\nimport Vue from 'vue'\nimport App from './App.vue'\nimport router from './router';\nimport store from './store';\nimport acl from './acl'; // import the instance of the defined ACL\n\nVue.config.productionTip = false;\n\nVue.use(acl); // install vue-simple-acl\n\nnew Vue({\n  router,\n  store,\n  render: h => h(App),\n}).$mount('#app')\n```\n\n<a name=\"acl-file\"></a>\n\n### ACL Rules File\nFor readability, it is recommend to defined your ACL rules in a separate file.\n```javascript\n// src/acl/index.js  OR  src/acl/index.ts\n\n// Import router if you are using the middleware on Vue Router\nimport router from \"../router\"; \n// Import store if you are using reactive Store/Pinia/Vuex as User data source\nimport store from \"../store\";\n\n// ----- VUE 3 Imports -----\nimport { computed } from 'vue'; // For VUE 3\nimport { createAcl, defineAclRules } from 'vue-simple-acl';\n\n// ----- VUE 2 Imports -----\nimport Vue from 'vue';\nimport VueCompositionAPI from '@vue/composition-api'; // Ensure this is installed\nVue.use(VueCompositionAPI); // VueCompositionAPI must be used as plugin before any function, otherwise see your console if warning/errpr\nimport { computed } from '@vue/composition-api'; // import computed function\nimport { createAcl, defineAclRules } from 'vue-simple-acl';\n\n// ---------------\n// The Vue Simple ACL option 'user' can be a user OBJECT, FUNCTION returning a user object\n// or an Asynchronous function returning a PROMISE of user object, suitable for performing fetch from API.\n\n// USER EXAMPLE 1: User {OBJECT}\nconst user = {\n  id: 1,\n  name: 'Victory Osayi',\n  is_editor: true,\n  is_admin: false,\n  // you can have role based permission list or access control list possibly from database\n  permissions: ['admin', 'owner', 'moderator', 'create-post', 'edit-post', 'delete-post']\n}\n\n// USER EXAMPLE 2: User object from a {FUNCTION} or computed property like from Pinia/Vuex Store\n// Suitable if you already has an existing logics authenticating and saving user data to Pinia/Vuex Store\nconst user2 = computed(() => store.state.auth.user);\n\n// USER EXAMPLE 3; User object from an Asynchronous {FUNCTION} / {PROMISE}:\n// Using Async/Promise requires instance of vue-router, the function will be auto hooked to beforeEach() peroperty of vue-router\nconst user3 = () => {\n  const authUserId = 1; // ID of authenticated user\n  return axios.get(`api/users/${authUserId}`)\n    .then((response) => response.data);\n}\n\nconst rules = () => defineAclRules((setRule) => {\n  // setRule('unique-ability', callbackFunction(user, arg1, arg2, ...) { });\n  // setRule(['unique-ability-1', 'unique-ability-2'], callbackFunction(user, arg1, arg2, ...) { });\n  \n  // Define a simple rule for ability with no argument\n  setRule('create-post', (user) => user.is_admin || user.is_editor);\n  setRule('is-admin', (user) => user.is_admin);\n  setRule('is-editor', (user) => user.is_editor);\n  // Define a simple rule for ability with an argument\n  setRule('edit-post', (user, post) => user.id === post.user_id);\n  setRule('delete-post', (user, post) => {\n    return user.id === post.user_id || user.is_admin;\n  });\n  // Define rule for array of multiple abilities that share same arguments and callback function\n  setRule(['publish-post', 'unpublish-post'], (user, post) => user.id === post.user_id);  \n  // Define rule for ability with multiple arguments\n  setRule('hide-comment', (user, post, comment) => {\n    return user.is_admin || user.id === post.user_id || (user.id === comment.user_id && post.id === comment.post_id);\n  });\n  setRule('moderator', (user) => user.permissions && user.permissions.includes('moderator'));\n});\n\nconst simpleAcl = createAcl({\n  user, // short for user: user\n  rules, // short for rules: rules\n  router, // OPTIONAL, short for router: router \n  // other optional vue-simple-acl options here... See Vue Simple ACL Options below\n});\n\nexport default simpleAcl;\n```\n\n\n<a name=\"usage-in-component\"></a>\n\n### Usage in component\n\nThe `v-can` directive can be used in different ways and you can apply one or more modifiers that alters the behaviour of the directive.\n\n```html\n<button v-can:create-post>Create Post</button>\n<button v-can:edit-post=\"{ id: 100, user_id: 1, title: 'First Post' }\">Edit</button>\n<button v-can:edit-post=\"postData\">Edit</button>\n```\nAlternative you can use the sematic alias;\n```html\n<button v-permission:create-post>Create Post</button>\n<button v-role:admin>Create Post</button>\n<button v-role-or-permission=\"['admin', 'create-post']\">Edit</button>\n```\n\n#### `hide` modifier\nThis is the default behaviour of the `v-can` directive, it remove the component or element from the DOM more like `v-if`.\nYou're not required to apply it unless you want to explicitly state the behavior.\n```html\n<button v-can:edit-post.hide=\"postData\">Edit</button>\n```\n\n#### `disable` modifier\nThe `disable` modifier applies the disabled attribute to the tag, e.g. to disable a button or input that you are not allowed to use or edit respectively.\n```html\n<button v-can:edit-post.disable=\"postData\">Edit</button>\n<input v-can:edit-post.disable=\"post\" v-model=\"postTitle\" type=\"text\">\n```\n\n#### `readonly` modifier\nThe `readonly` modifier applies the readonly attribute to the tag, e.g. to make an input read only if you don't have permission to edit.\n```html\n<input v-can:edit-post.readonly=\"post\" v-model=\"postTitle\" type=\"text\">\n```\n\n#### `not` modifier\nThe `not` modifier reverses the ACL query. In this example only if you cannot delete the post the div element is shown.\n```html\n<div v-can:delete-post.not=\"postData\">You can not delete post created by you, ask admin for help.</div>\n```\n\n#### `any` modifier\nBy default `v-can` directive with value that contains array of multiple abilities and ability arguments will be authorized if all specified abilities passes.\nThe `any` modifier authorized if atleast one or any of specified abilities and ability arguments passes.\n```html\n<!-- Authorized if both abilities passes -->\n<button v-can=\"['create-post', ['edit-post', post]]\">Create Post</button>\n<!-- Authorized if any of the abilities passes -->\n<button v-can.any=\"[['edit-post', post], ['delete-post', post]]\">Manage Post</button>\n```\n\n<a name=\"using-helper\"></a>\n\n### Using helper function in component\n\nYou can also use the helper function $can directly in component and javascript:\n```html\n<form v-if=\"$can('edit-post', post)\">\n    <input type=\"text\" :value=\"post.title\">\n    ...\n</form>\n```\nor in Option API\n```javascript\nif (this.$can('edit-post', post)) {\n  axios.put(`/api/posts/${post.id}`, postData)\n}\n```\n\n<a name=\"composition-api\"></a>\n\n### Using helper function in `setup` Vue's [Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html)\n\nThe introduction of `setup` and Vue's [Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html), open up new possibilities but to be able to get the full potential out of Vue Simple ACL, we will need to use composable functions to replace access to this.\n```javascript\nimport { useAcl } from 'vue-simple-acl';\n\nexport default {\n  setup() {\n    const acl = useAcl();\n\n    if (acl.can('edit-post', post)) {\n      axios.put(`/api/posts/${post.id}`, postData)\n    }\n\n    if (acl.can('hide-comment', [post, comment])) {\n      // Execute this block if user can hide comment of a post\n    }\n\n    if (acl.can.not('edit-post', post)) {\n      // Execute this block if user can not edit post\n    }\n\n    if (acl.can.any(['is-admin', 'is-editor'])) {\n      // Execute this block if user is admin OR is editor\n    }\n\n    if (acl.can.any([ 'is-admin', ['delete-post', post] ])) {\n      // Execute this block if user is admin OR can delete post\n    }\n\n    // Get data of the defined ACL User being validated\n    const user = acl.user;\n    const user = acl.getUser();\n  }\n}\n```\n\n<a name=\"middleware-for-vue-router\"></a>\n\n### Middleware for [Vue Router](https://next.router.vuejs.org/)\n\nTo integrate Vue Router, hook up the instance of `vue-router`'s `createRouter({..})` during setup of the Vue Simple ACL.\n\n```javascript\nconst simpleAcl = createAcl({\n  user, // short for user: user\n  rules, // short for rules: rules\n  router, // short for router: router\n  onDeniedRoute: '/unauthorized' // OR { path: '/unauthorized' } OR { name: 'unauthorized', replace: true} or '$from'\n});\napp.use(simpleAcl);\n```\n\nYou configure routes by adding `can` meta property to the route. E.g. if a router requires create post permission:\n```javascript\n{\n  path: 'posts/create',\n  name: 'createPost',\n  component: CreatePost,\n  meta: {\n    can: 'create-post',\n    onDeniedRoute: '/unauthorized' // value of onDeniedRoute option will be used if not set\n  }\n}\n```\nIf you have a rule that requires multiple abilities, you can do the following:\n```javascript\n{\n  path: 'posts/create',\n  name: 'createPost',\n  component: CreatePost,\n  meta: {\n    can: ['is-admin', 'create-post'],\n    onDeniedRoute: { name: 'unauthorizedPage', replace: true }\n  }\n}\n```\nor using `not` modifier\n```javascript\n{\n  path: 'posts/create',\n  name: 'createPost',\n  component: CreatePost,\n  meta: {\n    notCan: 'moderator',\n    onDeniedRoute: { name: 'unauthorizedPage', replace: true }\n  }\n}\n```\nor using `any` modifier\n```javascript\n{\n  path: 'posts/create',\n  name: 'createPost',\n  component: CreatePost,\n  meta: {\n    anyCan: ['is-admin', 'create-post'],\n    onDeniedRoute: { name: 'unauthorizedPage', replace: true }\n  }\n}\n```\nYou can also have an async evaluation by providing a callback that returns a promise the following:\n```javascript\n{\n  path: 'posts/:postId',\n  component: PostEditor,\n  meta: {\n    can: (to, from, can) => {        \n      return axios.get(`/api/posts/${to.params.id}`)\n        .then((response) => can('edit-post', response.data));\n    },\n    onDeniedRoute: '/unauthorized'\n  }\n}\n```\nor using `any` modifier\n```javascript\n{\n  path: 'posts/:postId/publish',\n  component: ManagePost,\n  meta: {\n    anyCan: (to, from, anyCan) => {        \n      return axios.get(`/api/posts/${to.params.id}/publish`)\n        .then((response) => anyCan(['is-admin', ['edit-post', response.data]]));\n    },\n    onDeniedRoute: '/unauthorized'\n  }\n}\n```\nor get the data of the defined ACL user in the evaluations by passing `user` as the optional **fourth** argument to the defined ACL meta function\n```javascript\n{\n  path: 'posts/:postId/publish',\n  component: ManagePost,\n  meta: {\n    anyCan: (to, from, anyCan, user) => {        \n      return axios.get(`/api/users/${user.id}/posts/${to.params.id}/publish`)\n        .then((response) => anyCan(['is-admin', ['edit-post', response.data]]));\n    },\n    onDeniedRoute: '/unauthorized'\n  }\n}\n```\n\n<a name=\"vue-router-ondeniedroute\"></a>\n\n#### `onDeniedRoute` meta property\n\nBy default if you omit the 'onDeniedRoute' property from the a routes meta a denied check will redirect to a value of Vue Simple Acl's `createAcl` option `onDeniedRoute` which is `/` by default. You can change this behaviour by setting the `createAcl` option `onDeniedRoute`. This is useful if you use the package in an authentication or authorization flow by redirecting to unauthorized page if access is denied.\n\nYou can also use an object for more options ([see guards section in docs](https://next.router.vuejs.org/guide/advanced/navigation-guards.html)):\n```javascript\nonDeniedRoute: { path: '/login': replace: true }\n```\nThis will use replace rather than push when redirecting to the login page.\n#### $from as value `onDeniedRoute`\n```javascript\nonDeniedRoute: '$from'\n```\nYou can set the onDeniedRoute to the special value `'$from'` which will return the user to wherever they came from\n\n<a name=\"vue-router-meta\"></a>\n\n### Vue Router `meta` Properties\n\n| Property Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| **can** or **allCan**| `string` OR `array` of abilities OR `function` of asynchronous evaluation: <span style=\"white-space:nowrap;\">`(to, from, can, user?) => {}`</span> | None | Equivalent of `$can()` and `v-can=\"\"` |\n| **notCan** or **canNot** | `string` OR `array` of abilities OR `function` of asynchronous evaluation: <span style=\"white-space:nowrap;\">`(to, from, notCan, user?)`</span> | None | Equivalent of `$can.not()` and `v-can.not=\"\"` |\n| **anyCan** or **canAny**| `string` OR `array` of abilities OR `function` of asynchronous evaluation: <span style=\"white-space:nowrap;\">`(to, from, anyCan, user?)`</span> | None | Equivalent of `$can.any()` and `v-can.any=\"\"` |\n| **onDeniedRoute** | `string` OR `object` of `route()` option | Value of the default option `onDeniedRoute`  | A route to redirect to when `can|notCan|anyCan` evaluation is denied. e.g string path `'/unauthorized'` OR router option `{ path: '/unauthorized' }` OR `{ name: 'unauthorizedPage', replace: true }` OR special value **`'$from'`** which returns back to the request URI |\n\n\n<a name=\"semantic-alias\"></a>\n\n## Semantic Alias directives and methods\nVue Simple ACL also provides some directives and methods in different verb as alias for default directive and helper function. You can use these aliases in place of `v-can` directive, `$can` helper function and vue router `can:` meta property for better semantic. See below table.\n\n| Alias Name | Usage |\n| --- | --- |\n| Permission | As Directives:<br>`v-permission:create-post`<br>`v-permission=\"'create-post'\"`<br> `v-permission.not=\"'create-post'\"`<br> `v-permission.any=\"['create-post', ['edit-post', post]]\"` <br><br> In Component:<br> `$acl.permission('create-post')`<br> `$acl.notPermission('create-post')`<br> `$acl.anyPermission(['create-post', ['edit-post', post]])` <br><br> In Option API:<br> `this.$acl.permission('create-post')`<br> `this.$acl.notPermission('create-post')`<br> `this.$acl.anyPermission(['create-post', ['edit-post', post]])` <br><br> In Composition API/`setup()`:<br> `const acl = useAcl();`<br> `acl.permission('create-post')`<br> `acl.notPermission('create-post')`<br> `acl.anyPermission(['create-post', ['edit-post', post]])` <br><br> In Vue Router `meta` Property:<br> `permission: 'create-post'`<br> `notPermission: ['create-post', 'create-category']` <br><br> `anyPermission: (to, from, anyPermission) => {`<br>&nbsp;&nbsp;`return axios.get(`\\``/api/posts/${to.params.id}`\\``)`<br>&nbsp;&nbsp;`.then((response) => anyPermission(['create-post', ['edit-post', response.data]]));`<br>`}` |\n| Role | As Directives:<br>`v-role:admin`<br>`v-role=\"'admin'\"`<br> `v-role.not=\"'editor'\"`<br> `v-role.any=\"['admin', 'editor']\"` <br><br> In Component:<br> `$acl.role('admin')`<br> `$acl.notRole('editor')`<br> `$acl.anyRole(['admin', 'editor'])` <br><br> In Option API:<br> `this.$acl.role('admin')`<br> `this.$acl.notRole('editor')`<br> `this.$acl.anyRole(['admin', 'editor'])` <br><br> In Composition API/`setup()`:<br> `const acl = useAcl();`<br> `acl.role('admin')`<br> `acl.notRole('editor')`<br> `acl.anyRole(['admin', 'editor'])` <br><br> In Vue Router `meta` Property:<br> `role: 'admin'`<br> `notRole: 'editor'` <br> `anyRole: ['admin', 'editor']` |\n| Role Or Permission | As Directives:<br>`v-role-or-permission=\"['admin', 'create-post']\"`<br> `v-role-or-permission.not=\"['editor', 'create-post']\"`<br> `v-role-or-permission.any=\"['admin', 'create-post', ['edit-post', post]]\"` <br><br> In Component:<br> `$acl.roleOrPermission(['admin', 'create-post'])`<br> `$acl.notRoleOrPermission(['editor', 'create-post'])`<br> `$acl.anyRoleOrPermission(['admin', 'create-post', ['edit-post', post]])` <br><br> In Option API:<br> `this.$acl.roleOrPermission(['admin', 'create-post'])`<br> `this.$acl.notRoleOrPermission(['editor', 'create-post'])`<br> `this.$acl.anyRoleOrPermission(['admin', 'create-post', ['edit-post', post]])` <br><br> In Composition API/`setup()`:<br> `const acl = useAcl();`<br> `acl.roleOrPermission(['admin', 'create-post'])`<br> `acl.notRoleOrPermission(['editor', 'create-post'])`<br> `acl.anyRoleOrPermission(['admin', 'create-post', ['edit-post', post]])` <br><br> In Vue Router `meta` Property:<br> `roleOrPermission: ['admin', 'create-post']`<br> `notRoleOrPermission: ['editor', 'create-post', 'create-category']` <br><br> `anyRoleOrPermission: (to, from, anyRoleOrPermission) => {`<br>&nbsp;&nbsp;`return axios.get(`\\``/api/posts/${to.params.id}`\\``)`<br>&nbsp;&nbsp;`.then((response) => anyRoleOrPermission(['admin', 'create-post', ['edit-post', response.data]]));`<br>`}` |\n| User | Get the data of the defined ACL user. <br><br> In Component:<br> `$acl.user; // returns user object`<br>`$acl.getUser(); // returns user object` <br><br> In Option API:<br> `this.$acl.user; // returns user object`<br>`this.$acl.getUser(); // returns user object` <br><br> In Composition API/`setup()`:<br> `const acl = useAcl();`<br> `acl.user; // returns user object`<br>`acl.getUser(); // returns user object` <br><br> In Vue Router `meta` Property:<br> _Pass `user` as the fourth argument to the defined ACL meta function_ <br><br> `roleOrPermission: (to, from, roleOrPermission, user) => {`<br>&nbsp;&nbsp;`return axios.get(`\\``/api/users/${user.id}/posts/${to.params.id}`\\``)`<br>&nbsp;&nbsp;`.then((response) => roleOrPermission(['admin', ['edit-post', response.data]]));`<br>`}` |\n\n\n<a name=\"options\"></a>\n\n## Vue Simple ACL Options \n can be a user OBJECT, FUNCTION returning a user object\n// or an Asynchronous function returning a PROMISE of user object, suitable for performing fetch from API.\n\n| Option Name | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| **user** | `object` or a `function|async function/Promise` returning user object. <br> *Using Async/Promise requires instance of `vue-router`, the function will be auto hooked to `beforeEach()` peroperty of vue-router.* | Yes | None | Authenticated user's data e.g object or function or async function/promise returning `{ id: 1, name: 'Victory Osayi', is_admin: true, ... }` |\n| **rules** | `function` | Yes | None | function returning instance of `defineAclRules()` e.g `() => defineAclRules((setRule) => {...}` |\n| **directiveName** | `object` or a `function` returning user object | No | `'can'` |  You can set a custom directive name if the default name conflicts with other installed plugins. e.g `'custom-can'` then in component like `v-custom-can=\"\"` |\n| **helperName** | `object` or a `function` returning user object | No | `'$can'` | You can set a custom helper name if the default name conflicts with other installed plugins. e.g `'$customCan'`, then use in component like `'$customCan()'` or `'$customCan.not()'` |\n| **enableSematicAlias** | `boolean` | No | `true` | You can enable or disable the sematic alias directives and methods e.g `v-role`, `v-permission`, `$acl.*`, etc. [See Semantic Alias](#sematic-alias)\n| **router** | `vue-router` | No | None | Inte |\n| **onDeniedRoute** | `string` or `object` | No | `/` | A route to redirect to when `can` evaluation is denied. e.g string path `'/unauthorized'` OR router option `{ path: '/unauthorized' }` OR `{ name: 'unauthorizedPage', replace: true }` OR special value `'$from'` which returns back to the request URI |\n\n\n<a name=\"todo\"></a>\n\n## TODO\n\n1. Chore: Write basic tests\n2. A documentation page with vitepress\n\n<a name=\"contributing\"></a>\n\n## 🤝 Contributing\n\n1. Fork this repository.\n2. Create new branch with feature name.\n3. Go to example folder and run `npm install` and `npm run serve`.\n4. The plugin sources files is located in `/src/*`.\n5. Commit and set commit message with feature name.\n6. Push your code to your fork repository.\n7. Create pull request. 🙂\n\n\n<a name=\"support\"></a>\n\n## ⭐️ Support\n\nIf you like this project, You can support me with starring ⭐ this repository, [buy me a coffee](https://www.patreon.com/victoryosayi) or [become a patron](https://www.patreon.com/victoryosayi).\n\n\n<a name=\"license\"></a>\n\n## 📄 License\n\n[MIT](LICENSE)\n\nDeveloped by [Victory Osayi](https://github.com/victorybiz) with ❤️ and ☕️ from Benin City, Edo, Nigeria.\n","readmeFilename":"README.md"}