locator-ars-lib 1.0.1 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/locator-ars-lib.es.js +12 -11
- package/dist/locator-ars-lib.es.js.map +1 -0
- package/dist/locator-ars-lib.umd.js +2 -1
- package/dist/locator-ars-lib.umd.js.map +1 -0
- package/package.json +23 -12
- package/examples/BasicUsage.vue +0 -132
- package/src/components/Check.vue +0 -33
- package/src/composables/usePermissions.ts +0 -57
- package/src/directives/vCan.ts +0 -55
- package/src/index.ts +0 -20
- package/src/plugin.ts +0 -23
- package/src/services/permissionsService.ts +0 -50
- package/tsconfig.json +0 -32
- package/tsconfig.node.json +0 -10
- package/vite.config.ts +0 -23
@@ -1,6 +1,6 @@
|
|
1
1
|
var h = Object.defineProperty;
|
2
2
|
var y = (e, s, n) => s in e ? h(e, s, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[s] = n;
|
3
|
-
var o = (e, s, n) =>
|
3
|
+
var o = (e, s, n) => y(e, typeof s != "symbol" ? s + "" : s, n);
|
4
4
|
import { inject as v, ref as l, computed as m, watch as _, onUnmounted as g, defineComponent as k, toRefs as w, renderSlot as u } from "vue";
|
5
5
|
import P from "axios";
|
6
6
|
class S {
|
@@ -38,18 +38,18 @@ const $ = {
|
|
38
38
|
e.provide(f, n);
|
39
39
|
}
|
40
40
|
};
|
41
|
-
function
|
41
|
+
function p() {
|
42
42
|
const e = v(f);
|
43
43
|
if (!e)
|
44
44
|
throw new Error("Permissions plugin not installed!");
|
45
45
|
return e;
|
46
46
|
}
|
47
47
|
function D(e, s = {}) {
|
48
|
-
const n =
|
49
|
-
if (
|
48
|
+
const n = p(), a = l(null), i = l(!1), t = l(null), d = m(() => typeof e == "string" ? e : e.value), c = async () => {
|
49
|
+
if (d.value) {
|
50
50
|
i.value = !0, t.value = null;
|
51
51
|
try {
|
52
|
-
a.value = await n.can(
|
52
|
+
a.value = await n.can(d.value);
|
53
53
|
} catch (r) {
|
54
54
|
t.value = r instanceof Error ? r : new Error(String(r)), a.value = !1;
|
55
55
|
} finally {
|
@@ -101,32 +101,33 @@ const E = k({
|
|
101
101
|
function b(e, s, n, a, i, t) {
|
102
102
|
return e.can ? u(e.$slots, "default", { key: 0 }) : e.isLoading ? u(e.$slots, "loading", { key: 2 }) : u(e.$slots, "fallback", { key: 1 });
|
103
103
|
}
|
104
|
-
const
|
104
|
+
const U = /* @__PURE__ */ L(E, [["render", b]]), x = {
|
105
105
|
async mounted(e, s) {
|
106
106
|
const n = e.style.display;
|
107
107
|
e._permission_data = {
|
108
108
|
action: s.value,
|
109
109
|
originalDisplay: n
|
110
|
-
}, await
|
110
|
+
}, await p().can(s.value) || (e.style.display = "none");
|
111
111
|
},
|
112
112
|
async updated(e, s) {
|
113
113
|
(!e._permission_data || e._permission_data.action !== s.value) && (e._permission_data = {
|
114
114
|
action: s.value,
|
115
115
|
originalDisplay: e.style.display || ""
|
116
|
-
}, await
|
116
|
+
}, await p().can(s.value) ? e.style.display = e._permission_data.originalDisplay : e.style.display = "none");
|
117
117
|
},
|
118
118
|
unmounted(e) {
|
119
119
|
e._permission_data && (e.style.display = e._permission_data.originalDisplay, delete e._permission_data);
|
120
120
|
}
|
121
121
|
}, A = {
|
122
122
|
install(e, s) {
|
123
|
-
e.use($, s), e.component("Check",
|
123
|
+
e.use($, s), e.component("Check", U), e.directive("can", x);
|
124
124
|
}
|
125
125
|
};
|
126
126
|
export {
|
127
|
-
|
127
|
+
U as Check,
|
128
128
|
A as default,
|
129
129
|
C as setupPermissions,
|
130
130
|
D as usePermissions,
|
131
|
-
|
131
|
+
x as vCan
|
132
132
|
};
|
133
|
+
//# sourceMappingURL=locator-ars-lib.es.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"locator-ars-lib.es.js","sources":["../src/services/permissionsService.ts","../src/plugin.ts","../src/composables/usePermissions.ts","../src/components/Check.vue","../src/directives/vCan.ts","../src/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios'\n\nexport interface PermissionsOptions {\n baseUrl?: string\n endpoint?: string\n}\n\nexport class PermissionsService {\n private axios: AxiosInstance\n private cache: Map<string, boolean> = new Map()\n private endpoint: string\n\n constructor(options?: PermissionsOptions) {\n this.axios = axios.create({\n baseURL: options?.baseUrl || ''\n })\n this.endpoint = options?.endpoint || '/api/v1/dashboard/access'\n }\n\n async can(action: string): Promise<boolean> {\n // Check if we have a cached result\n if (this.cache.has(action)) {\n return this.cache.get(action) as boolean\n }\n\n try {\n const response = await this.axios.get(this.endpoint, {\n params: { action }\n })\n\n const allowed = response.data.allowed || false\n\n // Cache the result\n this.cache.set(action, allowed)\n\n return allowed\n } catch (error) {\n console.error(`Error checking permission for ${action}:`, error)\n return false\n }\n }\n\n clearCache(action?: string): void {\n if (action) {\n this.cache.delete(action)\n } else {\n this.cache.clear()\n }\n }\n} ","import { App, inject, InjectionKey } from 'vue'\nimport { PermissionsService, PermissionsOptions } from './services/permissionsService'\n\nexport const PermissionsKey: InjectionKey<PermissionsService> = Symbol('Permissions')\n\nexport function setupPermissions(options?: PermissionsOptions): PermissionsService {\n return new PermissionsService(options)\n}\n\nexport const PermissionsPlugin = {\n install(app: App, options?: PermissionsOptions) {\n const permissionsService = setupPermissions(options)\n app.provide(PermissionsKey, permissionsService)\n }\n}\n\nexport function usePermissionsService(): PermissionsService {\n const permissionsService = inject(PermissionsKey)\n if (!permissionsService) {\n throw new Error('Permissions plugin not installed!')\n }\n return permissionsService\n} ","import { ref, computed, Ref, watch, onUnmounted } from 'vue'\nimport { usePermissionsService } from '../plugin'\n\nexport interface UsePermissionsOptions {\n autoCheck?: boolean\n}\n\nexport function usePermissions(action: string | Ref<string>, options: UsePermissionsOptions = {}) {\n const permissionsService = usePermissionsService()\n const isAllowed = ref<boolean | null>(null)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n const actionValue = computed(() => {\n return typeof action === 'string' ? action : action.value\n })\n\n const checkPermission = async () => {\n if (!actionValue.value) return\n\n isLoading.value = true\n error.value = null\n\n try {\n isAllowed.value = await permissionsService.can(actionValue.value)\n } catch (err) {\n error.value = err instanceof Error ? err : new Error(String(err))\n isAllowed.value = false\n } finally {\n isLoading.value = false\n }\n }\n\n // Auto-check on mount if requested\n if (options.autoCheck !== false) {\n checkPermission()\n }\n\n // Re-check when action changes\n if (typeof action !== 'string') {\n const unwatch = watch(action, () => {\n checkPermission()\n })\n\n onUnmounted(() => {\n unwatch()\n })\n }\n\n return {\n isAllowed,\n isLoading,\n error,\n check: checkPermission,\n can: computed(() => isAllowed.value === true)\n }\n} ","<template>\n <slot v-if=\"can\" />\n <slot name=\"fallback\" v-else-if=\"!isLoading\" />\n <slot name=\"loading\" v-else />\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, toRefs, PropType } from 'vue';\nimport { usePermissions } from '../composables/usePermissions';\n\nexport default defineComponent({\n name: 'Check',\n props: {\n action: {\n type: String as PropType<string>,\n required: true\n },\n fallback: {\n type: Boolean,\n default: false\n }\n },\n setup(props) {\n const { action } = toRefs(props);\n const { can, isLoading } = usePermissions(action, { autoCheck: true });\n\n return {\n can,\n isLoading\n };\n }\n});\n</script> ","import { ObjectDirective, DirectiveBinding } from 'vue'\nimport { usePermissionsService } from '../plugin'\n\ninterface CanHTMLElement extends HTMLElement {\n _permission_data?: {\n action: string\n originalDisplay: string\n }\n}\n\nexport const vCan: ObjectDirective = {\n async mounted(el: CanHTMLElement, binding: DirectiveBinding) {\n // Store original display value\n const originalDisplay = el.style.display\n\n // Store action and original display for updates\n el._permission_data = {\n action: binding.value,\n originalDisplay\n }\n\n const permissionsService = usePermissionsService()\n const hasPermission = await permissionsService.can(binding.value)\n\n if (!hasPermission) {\n el.style.display = 'none'\n }\n },\n\n async updated(el: CanHTMLElement, binding: DirectiveBinding) {\n if (!el._permission_data || el._permission_data.action !== binding.value) {\n // Action has changed or directive is new\n el._permission_data = {\n action: binding.value,\n originalDisplay: el.style.display || ''\n }\n\n const permissionsService = usePermissionsService()\n const hasPermission = await permissionsService.can(binding.value)\n\n if (!hasPermission) {\n el.style.display = 'none'\n } else {\n el.style.display = el._permission_data.originalDisplay\n }\n }\n },\n\n unmounted(el: CanHTMLElement) {\n if (el._permission_data) {\n el.style.display = el._permission_data.originalDisplay\n delete el._permission_data\n }\n }\n} ","import { App } from 'vue'\nimport Check from './components/Check.vue'\nimport { usePermissions } from './composables/usePermissions'\nimport { PermissionsPlugin, setupPermissions } from './plugin'\nimport { vCan } from './directives/vCan'\n\n// Именованные экспорты\nexport {\n Check,\n usePermissions,\n setupPermissions,\n vCan\n}\n\n// Создаем основной объект плагина\nconst plugin = {\n install(app: App, options?: { baseUrl?: string }) {\n app.use(PermissionsPlugin, options)\n app.component('Check', Check)\n app.directive('can', vCan)\n }\n}\n\n// Экспортируем плагин как по умолчанию\nexport default plugin "],"names":["PermissionsService","options","__publicField","axios","action","allowed","error","PermissionsKey","setupPermissions","PermissionsPlugin","app","permissionsService","usePermissionsService","inject","usePermissions","isAllowed","ref","isLoading","actionValue","computed","checkPermission","err","unwatch","watch","onUnmounted","_sfc_main","defineComponent","props","toRefs","can","_ctx","_renderSlot","vCan","el","binding","originalDisplay","plugin","Check"],"mappings":"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"}
|
@@ -1 +1,2 @@
|
|
1
|
-
(function(n,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("vue"),require("axios")):typeof define=="function"&&define.amd?define(["exports","vue","axios"],i):(n=typeof globalThis<"u"?globalThis:n||self,i(n.LocatorArsLib={},n.Vue,n.axios))})(this,function(n,i,
|
1
|
+
(function(n,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("vue"),require("axios")):typeof define=="function"&&define.amd?define(["exports","vue","axios"],i):(n=typeof globalThis<"u"?globalThis:n||self,i(n.LocatorArsLib={},n.Vue,n.axios))})(this,function(n,i,o){"use strict";var $=Object.defineProperty;var L=(n,i,o)=>i in n?$(n,i,{enumerable:!0,configurable:!0,writable:!0,value:o}):n[i]=o;var u=(n,i,o)=>L(n,typeof i!="symbol"?i+"":i,o);class P{constructor(s){u(this,"axios");u(this,"cache",new Map);u(this,"endpoint");this.axios=o.create({baseURL:(s==null?void 0:s.baseUrl)||""}),this.endpoint=(s==null?void 0:s.endpoint)||"/api/v1/dashboard/access"}async can(s){if(this.cache.has(s))return this.cache.get(s);try{const a=(await this.axios.get(this.endpoint,{params:{action:s}})).data.allowed||!1;return this.cache.set(s,a),a}catch(r){return console.error(`Error checking permission for ${s}:`,r),!1}}clearCache(s){s?this.cache.delete(s):this.cache.clear()}}const p=Symbol("Permissions");function m(e){return new P(e)}const S={install(e,s){const r=m(s);e.provide(p,r)}};function d(){const e=i.inject(p);if(!e)throw new Error("Permissions plugin not installed!");return e}function h(e,s={}){const r=d(),a=i.ref(null),t=i.ref(!1),l=i.ref(null),_=i.computed(()=>typeof e=="string"?e:e.value),f=async()=>{if(_.value){t.value=!0,l.value=null;try{a.value=await r.can(_.value)}catch(c){l.value=c instanceof Error?c:new Error(String(c)),a.value=!1}finally{t.value=!1}}};if(s.autoCheck!==!1&&f(),typeof e!="string"){const c=i.watch(e,()=>{f()});i.onUnmounted(()=>{c()})}return{isAllowed:a,isLoading:t,error:l,check:f,can:i.computed(()=>a.value===!0)}}const g=i.defineComponent({name:"Check",props:{action:{type:String,required:!0},fallback:{type:Boolean,default:!1}},setup(e){const{action:s}=i.toRefs(e),{can:r,isLoading:a}=h(s,{autoCheck:!0});return{can:r,isLoading:a}}}),k=(e,s)=>{const r=e.__vccOpts||e;for(const[a,t]of s)r[a]=t;return r};function w(e,s,r,a,t,l){return e.can?i.renderSlot(e.$slots,"default",{key:0}):e.isLoading?i.renderSlot(e.$slots,"loading",{key:2}):i.renderSlot(e.$slots,"fallback",{key:1})}const y=k(g,[["render",w]]),v={async mounted(e,s){const r=e.style.display;e._permission_data={action:s.value,originalDisplay:r},await d().can(s.value)||(e.style.display="none")},async updated(e,s){(!e._permission_data||e._permission_data.action!==s.value)&&(e._permission_data={action:s.value,originalDisplay:e.style.display||""},await d().can(s.value)?e.style.display=e._permission_data.originalDisplay:e.style.display="none")},unmounted(e){e._permission_data&&(e.style.display=e._permission_data.originalDisplay,delete e._permission_data)}},C={install(e,s){e.use(S,s),e.component("Check",y),e.directive("can",v)}};n.Check=y,n.default=C,n.setupPermissions=m,n.usePermissions=h,n.vCan=v,Object.defineProperties(n,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
2
|
+
//# sourceMappingURL=locator-ars-lib.umd.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"locator-ars-lib.umd.js","sources":["../src/services/permissionsService.ts","../src/plugin.ts","../src/composables/usePermissions.ts","../src/components/Check.vue","../src/directives/vCan.ts","../src/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios'\n\nexport interface PermissionsOptions {\n baseUrl?: string\n endpoint?: string\n}\n\nexport class PermissionsService {\n private axios: AxiosInstance\n private cache: Map<string, boolean> = new Map()\n private endpoint: string\n\n constructor(options?: PermissionsOptions) {\n this.axios = axios.create({\n baseURL: options?.baseUrl || ''\n })\n this.endpoint = options?.endpoint || '/api/v1/dashboard/access'\n }\n\n async can(action: string): Promise<boolean> {\n // Check if we have a cached result\n if (this.cache.has(action)) {\n return this.cache.get(action) as boolean\n }\n\n try {\n const response = await this.axios.get(this.endpoint, {\n params: { action }\n })\n\n const allowed = response.data.allowed || false\n\n // Cache the result\n this.cache.set(action, allowed)\n\n return allowed\n } catch (error) {\n console.error(`Error checking permission for ${action}:`, error)\n return false\n }\n }\n\n clearCache(action?: string): void {\n if (action) {\n this.cache.delete(action)\n } else {\n this.cache.clear()\n }\n }\n} ","import { App, inject, InjectionKey } from 'vue'\nimport { PermissionsService, PermissionsOptions } from './services/permissionsService'\n\nexport const PermissionsKey: InjectionKey<PermissionsService> = Symbol('Permissions')\n\nexport function setupPermissions(options?: PermissionsOptions): PermissionsService {\n return new PermissionsService(options)\n}\n\nexport const PermissionsPlugin = {\n install(app: App, options?: PermissionsOptions) {\n const permissionsService = setupPermissions(options)\n app.provide(PermissionsKey, permissionsService)\n }\n}\n\nexport function usePermissionsService(): PermissionsService {\n const permissionsService = inject(PermissionsKey)\n if (!permissionsService) {\n throw new Error('Permissions plugin not installed!')\n }\n return permissionsService\n} ","import { ref, computed, Ref, watch, onUnmounted } from 'vue'\nimport { usePermissionsService } from '../plugin'\n\nexport interface UsePermissionsOptions {\n autoCheck?: boolean\n}\n\nexport function usePermissions(action: string | Ref<string>, options: UsePermissionsOptions = {}) {\n const permissionsService = usePermissionsService()\n const isAllowed = ref<boolean | null>(null)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n const actionValue = computed(() => {\n return typeof action === 'string' ? action : action.value\n })\n\n const checkPermission = async () => {\n if (!actionValue.value) return\n\n isLoading.value = true\n error.value = null\n\n try {\n isAllowed.value = await permissionsService.can(actionValue.value)\n } catch (err) {\n error.value = err instanceof Error ? err : new Error(String(err))\n isAllowed.value = false\n } finally {\n isLoading.value = false\n }\n }\n\n // Auto-check on mount if requested\n if (options.autoCheck !== false) {\n checkPermission()\n }\n\n // Re-check when action changes\n if (typeof action !== 'string') {\n const unwatch = watch(action, () => {\n checkPermission()\n })\n\n onUnmounted(() => {\n unwatch()\n })\n }\n\n return {\n isAllowed,\n isLoading,\n error,\n check: checkPermission,\n can: computed(() => isAllowed.value === true)\n }\n} ","<template>\n <slot v-if=\"can\" />\n <slot name=\"fallback\" v-else-if=\"!isLoading\" />\n <slot name=\"loading\" v-else />\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, toRefs, PropType } from 'vue';\nimport { usePermissions } from '../composables/usePermissions';\n\nexport default defineComponent({\n name: 'Check',\n props: {\n action: {\n type: String as PropType<string>,\n required: true\n },\n fallback: {\n type: Boolean,\n default: false\n }\n },\n setup(props) {\n const { action } = toRefs(props);\n const { can, isLoading } = usePermissions(action, { autoCheck: true });\n\n return {\n can,\n isLoading\n };\n }\n});\n</script> ","import { ObjectDirective, DirectiveBinding } from 'vue'\nimport { usePermissionsService } from '../plugin'\n\ninterface CanHTMLElement extends HTMLElement {\n _permission_data?: {\n action: string\n originalDisplay: string\n }\n}\n\nexport const vCan: ObjectDirective = {\n async mounted(el: CanHTMLElement, binding: DirectiveBinding) {\n // Store original display value\n const originalDisplay = el.style.display\n\n // Store action and original display for updates\n el._permission_data = {\n action: binding.value,\n originalDisplay\n }\n\n const permissionsService = usePermissionsService()\n const hasPermission = await permissionsService.can(binding.value)\n\n if (!hasPermission) {\n el.style.display = 'none'\n }\n },\n\n async updated(el: CanHTMLElement, binding: DirectiveBinding) {\n if (!el._permission_data || el._permission_data.action !== binding.value) {\n // Action has changed or directive is new\n el._permission_data = {\n action: binding.value,\n originalDisplay: el.style.display || ''\n }\n\n const permissionsService = usePermissionsService()\n const hasPermission = await permissionsService.can(binding.value)\n\n if (!hasPermission) {\n el.style.display = 'none'\n } else {\n el.style.display = el._permission_data.originalDisplay\n }\n }\n },\n\n unmounted(el: CanHTMLElement) {\n if (el._permission_data) {\n el.style.display = el._permission_data.originalDisplay\n delete el._permission_data\n }\n }\n} ","import { App } from 'vue'\nimport Check from './components/Check.vue'\nimport { usePermissions } from './composables/usePermissions'\nimport { PermissionsPlugin, setupPermissions } from './plugin'\nimport { vCan } from './directives/vCan'\n\n// Именованные экспорты\nexport {\n Check,\n usePermissions,\n setupPermissions,\n vCan\n}\n\n// Создаем основной объект плагина\nconst plugin = {\n install(app: App, options?: { baseUrl?: string }) {\n app.use(PermissionsPlugin, options)\n app.component('Check', Check)\n app.directive('can', vCan)\n }\n}\n\n// Экспортируем плагин как по умолчанию\nexport default plugin "],"names":["PermissionsService","options","__publicField","axios","action","allowed","error","PermissionsKey","setupPermissions","PermissionsPlugin","app","permissionsService","usePermissionsService","inject","usePermissions","isAllowed","ref","isLoading","actionValue","computed","checkPermission","err","unwatch","watch","onUnmounted","_sfc_main","defineComponent","props","toRefs","can","_ctx","_renderSlot","vCan","el","binding","originalDisplay","plugin","Check"],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
{
|
2
2
|
"name": "locator-ars-lib",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.4",
|
4
4
|
"description": "Permissions library for Vue 3 applications",
|
5
|
-
"
|
5
|
+
"type": "module",
|
6
|
+
"main": "./dist/locator-ars-lib.umd.js",
|
7
|
+
"module": "./dist/locator-ars-lib.es.js",
|
8
|
+
"exports": {
|
9
|
+
".": {
|
10
|
+
"import": "./dist/locator-ars-lib.es.js",
|
11
|
+
"require": "./dist/locator-ars-lib.umd.js"
|
12
|
+
}
|
13
|
+
},
|
6
14
|
"types": "types/index.d.ts",
|
15
|
+
"files": [
|
16
|
+
"dist",
|
17
|
+
"types"
|
18
|
+
],
|
7
19
|
"scripts": {
|
8
20
|
"build": "vue-tsc && vite build",
|
9
21
|
"test": "vitest run",
|
@@ -18,17 +30,16 @@
|
|
18
30
|
"author": "badkiko",
|
19
31
|
"license": "MIT",
|
20
32
|
"peerDependencies": {
|
21
|
-
"
|
22
|
-
"
|
33
|
+
"vue": "^3.0.0 || ^3.5.0",
|
34
|
+
"axios": "^1.7.9"
|
23
35
|
},
|
24
36
|
"devDependencies": {
|
25
|
-
"@types/node": "^
|
26
|
-
"@vitejs/plugin-vue": "^
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"
|
31
|
-
"vue": "^3.
|
32
|
-
"vue-tsc": "^1.0.9"
|
37
|
+
"@types/node": "^22.10.5",
|
38
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
39
|
+
"typescript": "~5.6.2",
|
40
|
+
"vite": "^6.0.5",
|
41
|
+
"vue-tsc": "^2.2.0",
|
42
|
+
"axios": "^1.7.9",
|
43
|
+
"vue": "^3.5.13"
|
33
44
|
}
|
34
45
|
}
|
package/examples/BasicUsage.vue
DELETED
@@ -1,132 +0,0 @@
|
|
1
|
-
<template>
|
2
|
-
<div class="example-container">
|
3
|
-
<h1>Permissions Examples</h1>
|
4
|
-
|
5
|
-
<!-- Пример использования компонента Check -->
|
6
|
-
<div class="example-block">
|
7
|
-
<h2>Using Check Component</h2>
|
8
|
-
|
9
|
-
<Check action="view_dashboard">
|
10
|
-
<div class="dashboard-panel">
|
11
|
-
<h3>Dashboard Content</h3>
|
12
|
-
<p>This content is only visible for users with 'view_dashboard' permission</p>
|
13
|
-
</div>
|
14
|
-
|
15
|
-
<template #fallback>
|
16
|
-
<div class="no-permission">
|
17
|
-
<p>You don't have permission to view the dashboard</p>
|
18
|
-
</div>
|
19
|
-
</template>
|
20
|
-
|
21
|
-
<template #loading>
|
22
|
-
<div class="loading">
|
23
|
-
<p>Loading permissions...</p>
|
24
|
-
</div>
|
25
|
-
</template>
|
26
|
-
</Check>
|
27
|
-
</div>
|
28
|
-
|
29
|
-
<!-- Пример использования директивы v-can -->
|
30
|
-
<div class="example-block">
|
31
|
-
<h2>Using v-can Directive</h2>
|
32
|
-
|
33
|
-
<button v-can="'edit_user'" class="action-button">
|
34
|
-
Edit User
|
35
|
-
</button>
|
36
|
-
|
37
|
-
<button v-can="'delete_user'" class="action-button danger">
|
38
|
-
Delete User
|
39
|
-
</button>
|
40
|
-
</div>
|
41
|
-
|
42
|
-
<!-- Пример использования composable usePermissions -->
|
43
|
-
<div class="example-block">
|
44
|
-
<h2>Using usePermissions Composable</h2>
|
45
|
-
|
46
|
-
<div class="permission-status">
|
47
|
-
<p>Can create project: <span :class="canCreateProject ? 'allowed' : 'denied'">{{ canCreateProject ? 'Yes' : 'No' }}</span></p>
|
48
|
-
<p>Is loading: {{ isLoadingPermission ? 'Yes' : 'No' }}</p>
|
49
|
-
<button @click="checkPermissionManually" class="action-button">
|
50
|
-
Check Again
|
51
|
-
</button>
|
52
|
-
</div>
|
53
|
-
|
54
|
-
<div v-if="canCreateProject" class="action-panel">
|
55
|
-
<button class="action-button primary">Create New Project</button>
|
56
|
-
</div>
|
57
|
-
</div>
|
58
|
-
</div>
|
59
|
-
</template>
|
60
|
-
|
61
|
-
<script setup lang="ts">
|
62
|
-
import { Check, usePermissions } from 'locator-ars-lib'
|
63
|
-
|
64
|
-
// Использование composable
|
65
|
-
const { can: canCreateProject, isLoading: isLoadingPermission, check: checkPermissionManually } = usePermissions('create_project')
|
66
|
-
</script>
|
67
|
-
|
68
|
-
<style scoped>
|
69
|
-
.example-container {
|
70
|
-
max-width: 800px;
|
71
|
-
margin: 0 auto;
|
72
|
-
padding: 20px;
|
73
|
-
font-family: Arial, sans-serif;
|
74
|
-
}
|
75
|
-
|
76
|
-
.example-block {
|
77
|
-
margin-bottom: 30px;
|
78
|
-
padding: 20px;
|
79
|
-
border: 1px solid #eee;
|
80
|
-
border-radius: 5px;
|
81
|
-
}
|
82
|
-
|
83
|
-
.dashboard-panel {
|
84
|
-
background-color: #f5f5f5;
|
85
|
-
padding: 15px;
|
86
|
-
border-radius: 4px;
|
87
|
-
}
|
88
|
-
|
89
|
-
.action-button {
|
90
|
-
padding: 8px 16px;
|
91
|
-
margin-right: 10px;
|
92
|
-
border: none;
|
93
|
-
border-radius: 4px;
|
94
|
-
background-color: #4a90e2;
|
95
|
-
color: white;
|
96
|
-
cursor: pointer;
|
97
|
-
}
|
98
|
-
|
99
|
-
.action-button.danger {
|
100
|
-
background-color: #e25c4a;
|
101
|
-
}
|
102
|
-
|
103
|
-
.action-button.primary {
|
104
|
-
background-color: #42b983;
|
105
|
-
}
|
106
|
-
|
107
|
-
.permission-status {
|
108
|
-
margin-bottom: 15px;
|
109
|
-
}
|
110
|
-
|
111
|
-
.allowed {
|
112
|
-
color: #42b983;
|
113
|
-
font-weight: bold;
|
114
|
-
}
|
115
|
-
|
116
|
-
.denied {
|
117
|
-
color: #e25c4a;
|
118
|
-
font-weight: bold;
|
119
|
-
}
|
120
|
-
|
121
|
-
.no-permission {
|
122
|
-
padding: 15px;
|
123
|
-
background-color: #ffeeee;
|
124
|
-
border-left: 4px solid #e25c4a;
|
125
|
-
}
|
126
|
-
|
127
|
-
.loading {
|
128
|
-
padding: 15px;
|
129
|
-
background-color: #eeeeff;
|
130
|
-
border-left: 4px solid #4a90e2;
|
131
|
-
}
|
132
|
-
</style>
|
package/src/components/Check.vue
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
<template>
|
2
|
-
<slot v-if="can" />
|
3
|
-
<slot name="fallback" v-else-if="!isLoading" />
|
4
|
-
<slot name="loading" v-else />
|
5
|
-
</template>
|
6
|
-
|
7
|
-
<script lang="ts">
|
8
|
-
import { defineComponent, toRefs, PropType } from 'vue';
|
9
|
-
import { usePermissions } from '../composables/usePermissions';
|
10
|
-
|
11
|
-
export default defineComponent({
|
12
|
-
name: 'Check',
|
13
|
-
props: {
|
14
|
-
action: {
|
15
|
-
type: String as PropType<string>,
|
16
|
-
required: true
|
17
|
-
},
|
18
|
-
fallback: {
|
19
|
-
type: Boolean,
|
20
|
-
default: false
|
21
|
-
}
|
22
|
-
},
|
23
|
-
setup(props) {
|
24
|
-
const { action } = toRefs(props);
|
25
|
-
const { can, isLoading } = usePermissions(action, { autoCheck: true });
|
26
|
-
|
27
|
-
return {
|
28
|
-
can,
|
29
|
-
isLoading
|
30
|
-
};
|
31
|
-
}
|
32
|
-
});
|
33
|
-
</script>
|
@@ -1,57 +0,0 @@
|
|
1
|
-
import { ref, computed, Ref, watch, onUnmounted } from 'vue'
|
2
|
-
import { usePermissionsService } from '../plugin'
|
3
|
-
|
4
|
-
export interface UsePermissionsOptions {
|
5
|
-
autoCheck?: boolean
|
6
|
-
}
|
7
|
-
|
8
|
-
export function usePermissions(action: string | Ref<string>, options: UsePermissionsOptions = {}) {
|
9
|
-
const permissionsService = usePermissionsService()
|
10
|
-
const isAllowed = ref<boolean | null>(null)
|
11
|
-
const isLoading = ref(false)
|
12
|
-
const error = ref<Error | null>(null)
|
13
|
-
|
14
|
-
const actionValue = computed(() => {
|
15
|
-
return typeof action === 'string' ? action : action.value
|
16
|
-
})
|
17
|
-
|
18
|
-
const checkPermission = async () => {
|
19
|
-
if (!actionValue.value) return
|
20
|
-
|
21
|
-
isLoading.value = true
|
22
|
-
error.value = null
|
23
|
-
|
24
|
-
try {
|
25
|
-
isAllowed.value = await permissionsService.can(actionValue.value)
|
26
|
-
} catch (err) {
|
27
|
-
error.value = err instanceof Error ? err : new Error(String(err))
|
28
|
-
isAllowed.value = false
|
29
|
-
} finally {
|
30
|
-
isLoading.value = false
|
31
|
-
}
|
32
|
-
}
|
33
|
-
|
34
|
-
// Auto-check on mount if requested
|
35
|
-
if (options.autoCheck !== false) {
|
36
|
-
checkPermission()
|
37
|
-
}
|
38
|
-
|
39
|
-
// Re-check when action changes
|
40
|
-
if (typeof action !== 'string') {
|
41
|
-
const unwatch = watch(action, () => {
|
42
|
-
checkPermission()
|
43
|
-
})
|
44
|
-
|
45
|
-
onUnmounted(() => {
|
46
|
-
unwatch()
|
47
|
-
})
|
48
|
-
}
|
49
|
-
|
50
|
-
return {
|
51
|
-
isAllowed,
|
52
|
-
isLoading,
|
53
|
-
error,
|
54
|
-
check: checkPermission,
|
55
|
-
can: computed(() => isAllowed.value === true)
|
56
|
-
}
|
57
|
-
}
|
package/src/directives/vCan.ts
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
import { ObjectDirective, DirectiveBinding } from 'vue'
|
2
|
-
import { usePermissionsService } from '../plugin'
|
3
|
-
|
4
|
-
interface CanHTMLElement extends HTMLElement {
|
5
|
-
_permission_data?: {
|
6
|
-
action: string
|
7
|
-
originalDisplay: string
|
8
|
-
}
|
9
|
-
}
|
10
|
-
|
11
|
-
export const vCan: ObjectDirective = {
|
12
|
-
async mounted(el: CanHTMLElement, binding: DirectiveBinding) {
|
13
|
-
// Store original display value
|
14
|
-
const originalDisplay = el.style.display
|
15
|
-
|
16
|
-
// Store action and original display for updates
|
17
|
-
el._permission_data = {
|
18
|
-
action: binding.value,
|
19
|
-
originalDisplay
|
20
|
-
}
|
21
|
-
|
22
|
-
const permissionsService = usePermissionsService()
|
23
|
-
const hasPermission = await permissionsService.can(binding.value)
|
24
|
-
|
25
|
-
if (!hasPermission) {
|
26
|
-
el.style.display = 'none'
|
27
|
-
}
|
28
|
-
},
|
29
|
-
|
30
|
-
async updated(el: CanHTMLElement, binding: DirectiveBinding) {
|
31
|
-
if (!el._permission_data || el._permission_data.action !== binding.value) {
|
32
|
-
// Action has changed or directive is new
|
33
|
-
el._permission_data = {
|
34
|
-
action: binding.value,
|
35
|
-
originalDisplay: el.style.display || ''
|
36
|
-
}
|
37
|
-
|
38
|
-
const permissionsService = usePermissionsService()
|
39
|
-
const hasPermission = await permissionsService.can(binding.value)
|
40
|
-
|
41
|
-
if (!hasPermission) {
|
42
|
-
el.style.display = 'none'
|
43
|
-
} else {
|
44
|
-
el.style.display = el._permission_data.originalDisplay
|
45
|
-
}
|
46
|
-
}
|
47
|
-
},
|
48
|
-
|
49
|
-
unmounted(el: CanHTMLElement) {
|
50
|
-
if (el._permission_data) {
|
51
|
-
el.style.display = el._permission_data.originalDisplay
|
52
|
-
delete el._permission_data
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
package/src/index.ts
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
import { App } from 'vue'
|
2
|
-
import Check from './components/Check.vue'
|
3
|
-
import { usePermissions } from './composables/usePermissions'
|
4
|
-
import { PermissionsPlugin, setupPermissions } from './plugin'
|
5
|
-
import { vCan } from './directives/vCan'
|
6
|
-
|
7
|
-
export {
|
8
|
-
Check,
|
9
|
-
usePermissions,
|
10
|
-
setupPermissions,
|
11
|
-
vCan
|
12
|
-
}
|
13
|
-
|
14
|
-
export default {
|
15
|
-
install(app: App, options?: { baseUrl?: string }) {
|
16
|
-
app.use(PermissionsPlugin, options)
|
17
|
-
app.component('Check', Check)
|
18
|
-
app.directive('can', vCan)
|
19
|
-
}
|
20
|
-
}
|
package/src/plugin.ts
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
import { App, inject, InjectionKey } from 'vue'
|
2
|
-
import { PermissionsService, PermissionsOptions } from './services/permissionsService'
|
3
|
-
|
4
|
-
export const PermissionsKey: InjectionKey<PermissionsService> = Symbol('Permissions')
|
5
|
-
|
6
|
-
export function setupPermissions(options?: PermissionsOptions): PermissionsService {
|
7
|
-
return new PermissionsService(options)
|
8
|
-
}
|
9
|
-
|
10
|
-
export const PermissionsPlugin = {
|
11
|
-
install(app: App, options?: PermissionsOptions) {
|
12
|
-
const permissionsService = setupPermissions(options)
|
13
|
-
app.provide(PermissionsKey, permissionsService)
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
export function usePermissionsService(): PermissionsService {
|
18
|
-
const permissionsService = inject(PermissionsKey)
|
19
|
-
if (!permissionsService) {
|
20
|
-
throw new Error('Permissions plugin not installed!')
|
21
|
-
}
|
22
|
-
return permissionsService
|
23
|
-
}
|
@@ -1,50 +0,0 @@
|
|
1
|
-
import axios, { AxiosInstance } from 'axios'
|
2
|
-
|
3
|
-
export interface PermissionsOptions {
|
4
|
-
baseUrl?: string
|
5
|
-
endpoint?: string
|
6
|
-
}
|
7
|
-
|
8
|
-
export class PermissionsService {
|
9
|
-
private axios: AxiosInstance
|
10
|
-
private cache: Map<string, boolean> = new Map()
|
11
|
-
private endpoint: string
|
12
|
-
|
13
|
-
constructor(options?: PermissionsOptions) {
|
14
|
-
this.axios = axios.create({
|
15
|
-
baseURL: options?.baseUrl || ''
|
16
|
-
})
|
17
|
-
this.endpoint = options?.endpoint || '/api/v1/dashboard/access'
|
18
|
-
}
|
19
|
-
|
20
|
-
async can(action: string): Promise<boolean> {
|
21
|
-
// Check if we have a cached result
|
22
|
-
if (this.cache.has(action)) {
|
23
|
-
return this.cache.get(action) as boolean
|
24
|
-
}
|
25
|
-
|
26
|
-
try {
|
27
|
-
const response = await this.axios.get(this.endpoint, {
|
28
|
-
params: { action }
|
29
|
-
})
|
30
|
-
|
31
|
-
const allowed = response.data.allowed || false
|
32
|
-
|
33
|
-
// Cache the result
|
34
|
-
this.cache.set(action, allowed)
|
35
|
-
|
36
|
-
return allowed
|
37
|
-
} catch (error) {
|
38
|
-
console.error(`Error checking permission for ${action}:`, error)
|
39
|
-
return false
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
|
-
clearCache(action?: string): void {
|
44
|
-
if (action) {
|
45
|
-
this.cache.delete(action)
|
46
|
-
} else {
|
47
|
-
this.cache.clear()
|
48
|
-
}
|
49
|
-
}
|
50
|
-
}
|
package/tsconfig.json
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"compilerOptions": {
|
3
|
-
"target": "ES2020",
|
4
|
-
"useDefineForClassFields": true,
|
5
|
-
"module": "ESNext",
|
6
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
7
|
-
"skipLibCheck": true,
|
8
|
-
"typeRoots": ["./node_modules/@types", "./types"],
|
9
|
-
|
10
|
-
/* Bundler mode */
|
11
|
-
"moduleResolution": "node",
|
12
|
-
"allowImportingTsExtensions": true,
|
13
|
-
"resolveJsonModule": true,
|
14
|
-
"isolatedModules": true,
|
15
|
-
"noEmit": true,
|
16
|
-
"jsx": "preserve",
|
17
|
-
"esModuleInterop": true,
|
18
|
-
|
19
|
-
/* Linting */
|
20
|
-
"strict": true,
|
21
|
-
"noUnusedLocals": true,
|
22
|
-
"noUnusedParameters": true,
|
23
|
-
"noFallthroughCasesInSwitch": true,
|
24
|
-
|
25
|
-
/* Type declarations */
|
26
|
-
"declaration": true,
|
27
|
-
"declarationDir": "dist",
|
28
|
-
"outDir": "dist"
|
29
|
-
},
|
30
|
-
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
31
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
32
|
-
}
|
package/tsconfig.node.json
DELETED
package/vite.config.ts
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
import { defineConfig } from 'vite'
|
2
|
-
import vue from '@vitejs/plugin-vue'
|
3
|
-
import { resolve } from 'path'
|
4
|
-
|
5
|
-
export default defineConfig({
|
6
|
-
plugins: [vue()],
|
7
|
-
build: {
|
8
|
-
lib: {
|
9
|
-
entry: resolve(__dirname, 'src/index.ts'),
|
10
|
-
name: 'LocatorArsLib',
|
11
|
-
fileName: (format) => `locator-ars-lib.${format}.js`
|
12
|
-
},
|
13
|
-
rollupOptions: {
|
14
|
-
external: ['vue', 'axios'],
|
15
|
-
output: {
|
16
|
-
globals: {
|
17
|
-
vue: 'Vue',
|
18
|
-
axios: 'axios'
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
23
|
-
})
|