# 🔐 v-permission

Vue directive for controlling element visibility based on user permissions.

Supports dynamic permission checks, customizable strategies, Nuxt, and Pinia.

---

## 📦 Installation

```bash
npm install v-permission-directive
# or
yarn add v-permission-directive
```

---

## 🚀 Usage

### Register globally (main.ts)

```ts
import { createApp } from "vue";
import App from "./App.vue";
import vPermission, {
  configurePermissionDirective,
} from "v-permission-directive";

const app = createApp(App);

configurePermissionDirective({
  getUserPermissions: () => ["view_dashboard", "edit_profile"],
});

app.directive("permission", vPermission);
app.mount("#app");
```

---

### 👁️ Basic Usage

```vue
<!-- Will be shown only if user has 'view_dashboard' permission -->
<button v-permission="'view_dashboard'">Dashboard</button>

<!-- Will be shown if user has ANY of the listed permissions -->
<button v-permission="['edit_user', 'delete_user']">Manage User</button>
```

---

## 🔄 Dynamic Updates

If user permissions change during runtime, call:

```ts
import { clearPermissionCache } from "v-permission-directive";
clearPermissionCache();
```

---

## 🔧 Advanced Configuration

```ts
configurePermissionDirective({
  getUserPermissions: async () => {
    const user = await fetchUser();
    return user.permissions;
  },
  strategy: "some", // or 'every' for AND logic
  fallback: "hide", // or 'disable'
});
```

---

## 🧪 Development Mode

Enable logging to debug permission checks:

```ts
import { setDevelopmentMode } from "v-permission-directive";
setDevelopmentMode(true);
```

---

## 🧠 Custom Strategies

```ts
configurePermissionDirective({
  strategyFn: (required, userPermissions) => {
    return (
      userPermissions.includes("super_admin") ||
      required.some((p) => userPermissions.includes(p))
    );
  },
});
```

---

## 🌐 Nuxt Support

Inside `plugins/v-permission.client.ts`:

```ts
import { defineNuxtPlugin } from "#app";
import vPermission, {
  configurePermissionDirective,
} from "v-permission-directive";

export default defineNuxtPlugin((nuxtApp) => {
  configurePermissionDirective({
    getUserPermissions: () => useAuthStore().permissions,
  });

  nuxtApp.vueApp.directive("permission", vPermission);
});
```

---

## 🧩 Pinia Example

```ts
import { useAuthStore } from "@/stores/auth";

configurePermissionDirective({
  getUserPermissions: () => useAuthStore().permissions,
});
```

---

## ✅ API Reference

### `v-permission="string | string[]"`

Required permission(s) to display the element.

### `configurePermissionDirective(options)`

| Option             | Type                                  | Default  | Description                                 |
| ------------------ | ------------------------------------- | -------- | ------------------------------------------- |
| getUserPermissions | `() => string[] \| Promise<string[]>` | `[]`     | Function to fetch user permissions          |
| strategy           | `'some' \| 'every'`                   | `'some'` | Whether to check for ANY or ALL permissions |
| strategyFn         | `Function`                            | -        | Custom check logic                          |
| fallback           | `'hide' \| 'disable'`                 | `'hide'` | What to do when permission fails            |

### `setDevelopmentMode(true)`

Enables debug logging

### `clearPermissionCache()`

Clears cached permissions (for dynamic updates)

---

## 🛠️ Best Practices

- Use meaningful permission keys like `user.create`, `user.delete`
- Always define fallback behavior
- Combine with route guards for full access control

---

## 📄 License

MIT © Kerolos
