UNPKG

vue-permission-directive

Version:

A flexible Vue 3 directive for managing user permissions with support for AND, OR, regex, and pattern-based checks.

178 lines (173 loc) 6.68 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); // ----------------------------- // 🔧 CONFIG // ----------------------------- let globalConfig = { permissions: null }; let isDevelopmentMode = false; const permissionCache = new Map(); const STORAGE_KEY = "__v_permission__"; // وهمي بسيط - غيّره حسب نوع التشفير الحقيقي اللي عندك const encrypt = (value) => btoa(JSON.stringify(value)); const decrypt = (value) => JSON.parse(atob(value)); const configurePermissionDirective = (permissions, options) => { var _a; globalConfig.permissions = permissions; isDevelopmentMode = (_a = options === null || options === void 0 ? void 0 : options.developmentMode) !== null && _a !== void 0 ? _a : false; permissionCache.clear(); // ✅ Store encrypted permissions try { const encrypted = encrypt(permissions); localStorage.setItem(STORAGE_KEY, encrypted); } catch (e) { isDevelopmentMode && console.warn("[v-permission] Failed to store permissions:", e); } }; const initPermissionDirectiveIfNeeded = () => { try { const stored = localStorage.getItem(STORAGE_KEY); if (stored) { const decrypted = decrypt(stored); configurePermissionDirective(decrypted); } } catch (e) { isDevelopmentMode && console.warn("[v-permission] Failed to init permissions:", e); } }; const setDevelopmentMode = (enabled) => { isDevelopmentMode = enabled; }; const clearPermissionCache = () => { permissionCache.clear(); }; // ----------------------------- // 🔍 INTERNAL HELPERS // ----------------------------- const getCurrentPermissions = () => { const { permissions } = globalConfig; return vue.isRef(permissions) ? permissions.value : permissions !== null && permissions !== void 0 ? permissions : []; }; const hasCachedPermission = (key) => permissionCache.has(key) ? permissionCache.get(key) : null; // ----------------------------- // ✅ hasPermission() // ----------------------------- const hasPermission = async (permissionValue) => { const currentPermissions = getCurrentPermissions(); const cacheKey = JSON.stringify(permissionValue); const cached = hasCachedPermission(cacheKey); if (cached !== null) return cached; const checkPermission = async (perm) => currentPermissions.includes(perm); const evaluate = async (value) => { var _a, _b; if (typeof value === "string") return await checkPermission(value); if (Array.isArray(value)) { const results = await Promise.all(value.map(hasPermission)); return results.some(Boolean); } if (typeof value === "object" && value.permissions && value.mode) { const perms = value.permissions; const mode = value.mode; const checks = { and: () => perms.every((p) => currentPermissions.includes(p)), or: () => perms.some((p) => currentPermissions.includes(p)), startWith: () => perms.some((p) => currentPermissions.some((u) => u.startsWith(p))), endWith: () => perms.some((p) => currentPermissions.some((u) => u.endsWith(p))), exact: () => perms.some((p) => currentPermissions.includes(p)), regex: () => perms.some((p) => { try { const r = new RegExp(p); return currentPermissions.some((u) => r.test(u)); } catch (e) { isDevelopmentMode && console.warn("[v-permission] Invalid regex", p, e); return false; } }), }; return (_b = (_a = checks[mode]) === null || _a === void 0 ? void 0 : _a.call(checks)) !== null && _b !== void 0 ? _b : false; } isDevelopmentMode && console.warn("[v-permission] Invalid permission value:", value); return false; }; const result = await evaluate(permissionValue); permissionCache.set(cacheKey, result); return result; }; // ----------------------------- // 🎯 v-permission Directive // ----------------------------- const vPermission = { mounted(el, binding) { var _a; const value = binding.value; const modifiers = binding.modifiers; const showOnly = binding.arg === "show"; const originalDisplay = el.style.display || ""; const applyPermission = async () => { var _a, _b; try { const allowed = await hasPermission(value); if (allowed) { if (showOnly) el.style.display = originalDisplay; } else { if (showOnly) el.style.display = "none"; else (_a = el.remove) === null || _a === void 0 ? void 0 : _a.call(el); } } catch (err) { isDevelopmentMode && console.warn("[v-permission] Error evaluating permission", err); if (showOnly) el.style.display = "none"; else (_b = el.remove) === null || _b === void 0 ? void 0 : _b.call(el); } }; if (!globalConfig.permissions) { isDevelopmentMode && console.warn("[v-permission] Permissions not configured"); if (!showOnly) (_a = el.remove) === null || _a === void 0 ? void 0 : _a.call(el); return; } if (modifiers.once) { applyPermission(); } else if (vue.isRef(globalConfig.permissions) && !modifiers.lazy) { vue.watchEffect(() => { applyPermission(); }); } else { applyPermission(); } }, }; // ----------------------------- // 🔌 Plugin Installer // ----------------------------- const PermissionPlugin = { install(app) { app.directive("permission", vPermission); }, }; exports.clearPermissionCache = clearPermissionCache; exports.configurePermissionDirective = configurePermissionDirective; exports.default = PermissionPlugin; exports.hasPermission = hasPermission; exports.initPermissionDirectiveIfNeeded = initPermissionDirectiveIfNeeded; exports.setDevelopmentMode = setDevelopmentMode; exports.vPermission = vPermission;