locator-ars-lib 1.1.1 → 1.1.2

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.
@@ -1,14 +1,14 @@
1
- var h = Object.defineProperty;
2
- var y = (e, s, i) => s in e ? h(e, s, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[s] = i;
3
- var c = (e, s, i) => y(e, typeof s != "symbol" ? s + "" : s, i);
4
- import { inject as v, ref as l, computed as p, watch as g, onUnmounted as _, defineComponent as k, toRefs as w, onMounted as P, renderSlot as d, createCommentVNode as C } from "vue";
5
- import S from "axios";
6
- class L {
1
+ var v = Object.defineProperty;
2
+ var g = (e, s, i) => s in e ? v(e, s, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[s] = i;
3
+ var o = (e, s, i) => g(e, typeof s != "symbol" ? s + "" : s, i);
4
+ import { inject as _, ref as l, computed as y, watch as k, onUnmounted as P, defineComponent as w, toRefs as C, onMounted as S, renderSlot as m, createCommentVNode as L } from "vue";
5
+ import $ from "axios";
6
+ class E {
7
7
  constructor(s) {
8
- c(this, "axios");
9
- c(this, "cache", /* @__PURE__ */ new Map());
10
- c(this, "endpoint");
11
- this.axios = S.create({
8
+ o(this, "axios");
9
+ o(this, "cache", /* @__PURE__ */ new Map());
10
+ o(this, "endpoint");
11
+ this.axios = $.create({
12
12
  baseURL: (s == null ? void 0 : s.baseUrl) || ""
13
13
  }), this.endpoint = (s == null ? void 0 : s.endpoint) || "/api/v1/dashboard/access";
14
14
  }
@@ -28,96 +28,101 @@ class L {
28
28
  s ? this.cache.delete(s) : this.cache.clear();
29
29
  }
30
30
  }
31
- let t = null;
32
- function $(e) {
33
- t = e;
31
+ let f = null;
32
+ const c = /* @__PURE__ */ new Map();
33
+ function b(e) {
34
+ f = e;
35
+ }
36
+ async function I(e) {
37
+ if (!f)
38
+ return console.warn("Permissions service not initialized yet."), !1;
39
+ if (!c.has(e)) {
40
+ const s = f.can(e).catch((i) => (console.error("Error checking permission:", i), c.delete(e), !1));
41
+ c.set(e, s);
42
+ }
43
+ return c.get(e);
34
44
  }
35
- const E = {
45
+ async function u(e, s, i) {
46
+ const n = e.style.display;
47
+ e._permission_data = {
48
+ action: s,
49
+ originalDisplay: n,
50
+ permissionChecked: !1
51
+ }, e.style.display = "none";
52
+ try {
53
+ const a = await I(s);
54
+ (i && a || !i && !a) && (e.style.display = n || ""), e._permission_data.permissionChecked = !0;
55
+ } catch (a) {
56
+ console.error("Error in directive processing:", a), i || (e.style.display = n || "");
57
+ }
58
+ }
59
+ const D = {
36
60
  async mounted(e, s) {
37
- const i = e.style.display;
38
- if (e._permission_data = {
39
- action: s.value,
40
- originalDisplay: i,
41
- permissionChecked: !1
42
- }, e.style.display = "none", !t) {
43
- console.warn("Permissions service not initialized yet. Element will remain hidden.");
44
- return;
45
- }
46
- try {
47
- await t.can(s.value) && (e.style.display = i || ""), e._permission_data.permissionChecked = !0;
48
- } catch (n) {
49
- console.error("Error checking permission:", n);
50
- }
61
+ await u(e, s.value, !0);
51
62
  },
52
63
  async updated(e, s) {
53
- var i;
54
- if (!e._permission_data || e._permission_data.action !== s.value) {
55
- const n = ((i = e._permission_data) == null ? void 0 : i.originalDisplay) || e.style.display || "";
56
- if (e._permission_data = {
57
- action: s.value,
58
- originalDisplay: n,
59
- permissionChecked: !1
60
- }, e.style.display = "none", !t) {
61
- console.warn("Permissions service not initialized yet. Element will remain hidden.");
62
- return;
63
- }
64
- try {
65
- await t.can(s.value) && (e.style.display = e._permission_data.originalDisplay || ""), e._permission_data.permissionChecked = !0;
66
- } catch (r) {
67
- console.error("Error checking permission:", r);
68
- }
69
- }
64
+ (!e._permission_data || e._permission_data.action !== s.value) && await u(e, s.value, !0);
70
65
  },
71
66
  unmounted(e) {
72
67
  e._permission_data && (e.style.display = e._permission_data.originalDisplay, delete e._permission_data);
73
68
  }
74
- }, f = Symbol("Permissions");
75
- function b(e) {
76
- const s = new L(e);
77
- return $(s), s;
69
+ }, M = {
70
+ async mounted(e, s) {
71
+ await u(e, s.value, !1);
72
+ },
73
+ async updated(e, s) {
74
+ (!e._permission_data || e._permission_data.action !== s.value) && await u(e, s.value, !1);
75
+ },
76
+ unmounted(e) {
77
+ e._permission_data && (e.style.display = e._permission_data.originalDisplay, delete e._permission_data);
78
+ }
79
+ }, h = Symbol("Permissions");
80
+ function U(e) {
81
+ const s = new E(e);
82
+ return b(s), s;
78
83
  }
79
- const D = {
84
+ const R = {
80
85
  install(e, s) {
81
- const i = b(s);
82
- e.provide(f, i), e.config.globalProperties.$permissions = i;
86
+ const i = U(s);
87
+ e.provide(h, i), e.config.globalProperties.$permissions = i;
83
88
  }
84
89
  };
85
- function I() {
86
- const e = v(f);
90
+ function V() {
91
+ const e = _(h);
87
92
  if (!e)
88
93
  throw new Error("Permissions plugin not installed!");
89
94
  return e;
90
95
  }
91
- function U(e, s = {}) {
92
- const i = I(), n = l(null), r = l(!1), a = l(null), m = p(() => typeof e == "string" ? e : e.value), u = async () => {
93
- if (m.value) {
94
- r.value = !0, a.value = null;
96
+ function j(e, s = {}) {
97
+ const i = V(), n = l(null), a = l(!1), r = l(null), p = y(() => typeof e == "string" ? e : e.value), d = async () => {
98
+ if (p.value) {
99
+ a.value = !0, r.value = null;
95
100
  try {
96
- n.value = await i.can(m.value);
97
- } catch (o) {
98
- a.value = o instanceof Error ? o : new Error(String(o)), n.value = !1;
101
+ n.value = await i.can(p.value);
102
+ } catch (t) {
103
+ r.value = t instanceof Error ? t : new Error(String(t)), n.value = !1;
99
104
  } finally {
100
- r.value = !1;
105
+ a.value = !1;
101
106
  }
102
107
  }
103
108
  };
104
- if (s.autoCheck !== !1 && u(), typeof e != "string") {
105
- const o = g(e, () => {
106
- u();
109
+ if (s.autoCheck !== !1 && d(), typeof e != "string") {
110
+ const t = k(e, () => {
111
+ d();
107
112
  });
108
- _(() => {
109
- o();
113
+ P(() => {
114
+ t();
110
115
  });
111
116
  }
112
117
  return {
113
118
  isAllowed: n,
114
- isLoading: r,
115
- error: a,
116
- check: u,
117
- can: p(() => n.value === !0)
119
+ isLoading: a,
120
+ error: r,
121
+ check: d,
122
+ can: y(() => n.value === !0)
118
123
  };
119
124
  }
120
- const z = k({
125
+ const q = w({
121
126
  name: "Check",
122
127
  props: {
123
128
  action: {
@@ -130,36 +135,37 @@ const z = k({
130
135
  }
131
136
  },
132
137
  setup(e) {
133
- const { action: s } = w(e), i = l(!0), { can: n, isLoading: r, check: a } = U(s, { autoCheck: !1 });
134
- return P(async () => {
135
- await a(), i.value = !1;
138
+ const { action: s } = C(e), i = l(!0), { can: n, isLoading: a, check: r } = j(s, { autoCheck: !1 });
139
+ return S(async () => {
140
+ await r(), i.value = !1;
136
141
  }), {
137
142
  can: n,
138
- isLoading: r,
143
+ isLoading: a,
139
144
  isInitialLoading: i
140
145
  };
141
146
  }
142
- }), M = (e, s) => {
147
+ }), z = (e, s) => {
143
148
  const i = e.__vccOpts || e;
144
- for (const [n, r] of s)
145
- i[n] = r;
149
+ for (const [n, a] of s)
150
+ i[n] = a;
146
151
  return i;
147
152
  };
148
- function R(e, s, i, n, r, a) {
149
- return e.can && !e.isInitialLoading ? d(e.$slots, "default", { key: 0 }) : !e.isLoading && !e.isInitialLoading && !e.can ? d(e.$slots, "fallback", { key: 1 }) : e.isLoading || e.isInitialLoading ? d(e.$slots, "loading", { key: 2 }) : C("", !0);
153
+ function B(e, s, i, n, a, r) {
154
+ return e.can && !e.isInitialLoading ? m(e.$slots, "default", { key: 0 }) : !e.isLoading && !e.isInitialLoading && !e.can ? m(e.$slots, "fallback", { key: 1 }) : e.isLoading || e.isInitialLoading ? m(e.$slots, "loading", { key: 2 }) : L("", !0);
150
155
  }
151
- const V = /* @__PURE__ */ M(z, [["render", R]]), B = {
156
+ const K = /* @__PURE__ */ z(q, [["render", B]]), G = {
152
157
  install(e, s) {
153
- e.use(D, s), e.component("Check", V), e.directive("can", E);
158
+ e.use(R, s), e.component("Check", K), e.directive("can", D), e.directive("cant", M);
154
159
  }
155
160
  };
156
161
  export {
157
- V as Check,
158
- B as default,
159
- $ as setPermissionsService,
160
- b as setupPermissions,
161
- U as usePermissions,
162
- I as usePermissionsService,
163
- E as vCan
162
+ K as Check,
163
+ G as default,
164
+ b as setPermissionsService,
165
+ U as setupPermissions,
166
+ j as usePermissions,
167
+ V as usePermissionsService,
168
+ D as vCan,
169
+ M as vCant
164
170
  };
165
171
  //# sourceMappingURL=locator-ars-lib.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"locator-ars-lib.es.js","sources":["../src/services/permissionsService.ts","../src/directives/vCan.ts","../src/plugin.ts","../src/composables/usePermissions.ts","../src/components/Check.vue","../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 { ObjectDirective, DirectiveBinding } from 'vue'\nimport { PermissionsService } from '../services/permissionsService'\n\ninterface CanHTMLElement extends HTMLElement {\n _permission_data?: {\n action: string\n originalDisplay: string\n permissionChecked?: boolean\n }\n}\n\n// Глобальный сервис проверки прав\nlet globalPermissionsService: PermissionsService | null = null;\n\n// Функция для установки экземпляра сервиса (будет вызываться при инициализации плагина)\nexport function setPermissionsService(service: PermissionsService): void {\n globalPermissionsService = service;\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 permissionChecked: false\n };\n\n // Скрываем элемент изначально до проверки прав\n el.style.display = 'none';\n\n if (!globalPermissionsService) {\n console.warn('Permissions service not initialized yet. Element will remain hidden.');\n return;\n }\n\n try {\n const hasPermission = await globalPermissionsService.can(binding.value);\n\n if (hasPermission) {\n // Показываем элемент только если есть права\n el.style.display = originalDisplay || '';\n }\n\n el._permission_data.permissionChecked = true;\n } catch (error) {\n console.error('Error checking permission:', error);\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 const originalDisplay = el._permission_data?.originalDisplay || el.style.display || '';\n\n el._permission_data = {\n action: binding.value,\n originalDisplay,\n permissionChecked: false\n };\n\n // Скрываем элемент при обновлении до проверки прав\n el.style.display = 'none';\n\n if (!globalPermissionsService) {\n console.warn('Permissions service not initialized yet. Element will remain hidden.');\n return;\n }\n\n try {\n const hasPermission = await globalPermissionsService.can(binding.value);\n\n if (hasPermission) {\n el.style.display = el._permission_data.originalDisplay || '';\n }\n\n el._permission_data.permissionChecked = true;\n } catch (error) {\n console.error('Error checking permission:', error);\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, inject, InjectionKey } from 'vue'\nimport { PermissionsService, PermissionsOptions } from './services/permissionsService'\nimport { setPermissionsService } from './directives/vCan'\n\nexport const PermissionsKey: InjectionKey<PermissionsService> = Symbol('Permissions')\n\nexport function setupPermissions(options?: PermissionsOptions): PermissionsService {\n const service = new PermissionsService(options);\n // Устанавливаем глобальный сервис для директивы\n setPermissionsService(service);\n return service;\n}\n\nexport const PermissionsPlugin = {\n install(app: App, options?: PermissionsOptions) {\n const permissionsService = setupPermissions(options);\n app.provide(PermissionsKey, permissionsService);\n\n // Добавим сервис в глобальные свойства Vue для доступа откуда угодно\n app.config.globalProperties.$permissions = 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 && !isInitialLoading\" />\n <slot name=\"fallback\" v-else-if=\"!isLoading && !isInitialLoading && !can\" />\n <slot name=\"loading\" v-else-if=\"isLoading || isInitialLoading\" />\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, toRefs, PropType, ref, onMounted } 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 isInitialLoading = ref(true);\n const { can, isLoading, check } = usePermissions(action, { autoCheck: false });\n \n onMounted(async () => {\n await check();\n isInitialLoading.value = false;\n });\n\n return {\n can,\n isLoading,\n isInitialLoading\n };\n }\n});\n</script> ","import { App } from 'vue'\nimport Check from './components/Check.vue'\nimport { usePermissions } from './composables/usePermissions'\nimport { PermissionsPlugin, setupPermissions, usePermissionsService } from './plugin'\nimport { vCan, setPermissionsService } from './directives/vCan'\n\n// Именованные экспорты\nexport {\n Check,\n usePermissions,\n setupPermissions,\n vCan,\n usePermissionsService,\n setPermissionsService\n}\n\n// Создаем основной объект плагина\nconst plugin = {\n install(app: App, options?: { baseUrl?: string }) {\n // Важно: сначала нужно инициализировать PermissionsPlugin для provide/inject механизма\n app.use(PermissionsPlugin, options)\n\n // Затем регистрируем компонент и директиву\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","globalPermissionsService","setPermissionsService","service","vCan","el","binding","originalDisplay","_a","PermissionsKey","setupPermissions","PermissionsPlugin","app","permissionsService","usePermissionsService","inject","usePermissions","isAllowed","ref","isLoading","actionValue","computed","checkPermission","err","unwatch","watch","onUnmounted","_sfc_main","defineComponent","props","toRefs","isInitialLoading","can","check","onMounted","_ctx","_renderSlot","_createCommentVNode","plugin","Check"],"mappings":"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"}
1
+ {"version":3,"file":"locator-ars-lib.es.js","sources":["../src/services/permissionsService.ts","../src/directives/vCan.ts","../src/plugin.ts","../src/composables/usePermissions.ts","../src/components/Check.vue","../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 { ObjectDirective, DirectiveBinding } from 'vue'\nimport { PermissionsService } from '../services/permissionsService'\n\ninterface CanHTMLElement extends HTMLElement {\n _permission_data?: {\n action: string\n originalDisplay: string\n permissionChecked?: boolean\n }\n}\n\n// Глобальный сервис проверки прав\nlet globalPermissionsService: PermissionsService | null = null;\n\n// Кэш результатов проверки прав для избежания дублирования запросов\nconst permissionsCache: Map<string, Promise<boolean>> = new Map();\n\n// Функция для установки экземпляра сервиса (будет вызываться при инициализации плагина)\nexport function setPermissionsService(service: PermissionsService): void {\n globalPermissionsService = service;\n}\n\n// Общая функция проверки прав для обеих директив\nasync function checkPermission(action: string): Promise<boolean> {\n if (!globalPermissionsService) {\n console.warn('Permissions service not initialized yet.');\n return false;\n }\n\n // Проверяем есть ли запрос с таким же action уже в процессе выполнения\n if (!permissionsCache.has(action)) {\n // Создаем Promise для проверки прав и сохраняем в кэш\n const permissionPromise = globalPermissionsService.can(action)\n .catch(error => {\n console.error('Error checking permission:', error);\n permissionsCache.delete(action);\n return false;\n });\n\n permissionsCache.set(action, permissionPromise);\n }\n\n // Возвращаем результат из кэша (либо готовый, либо ожидающий Promise)\n return permissionsCache.get(action) as Promise<boolean>;\n}\n\n// Общая логика для обработки элементов, применяемая обеими директивами\nasync function processElement(el: CanHTMLElement, action: string, showWhenAllowed: boolean) {\n const originalDisplay = el.style.display;\n\n // Store action and original display for updates\n el._permission_data = {\n action,\n originalDisplay,\n permissionChecked: false\n };\n\n // Скрываем элемент изначально до проверки прав\n el.style.display = 'none';\n\n try {\n const hasPermission = await checkPermission(action);\n\n // Показываем элемент в зависимости от режима и результата проверки\n if ((showWhenAllowed && hasPermission) || (!showWhenAllowed && !hasPermission)) {\n el.style.display = originalDisplay || '';\n }\n\n el._permission_data.permissionChecked = true;\n } catch (error) {\n console.error('Error in directive processing:', error);\n // При ошибке для v-cant показываем элемент\n if (!showWhenAllowed) {\n el.style.display = originalDisplay || '';\n }\n }\n}\n\nexport const vCan: ObjectDirective = {\n async mounted(el: CanHTMLElement, binding: DirectiveBinding) {\n await processElement(el, binding.value, true);\n },\n\n async updated(el: CanHTMLElement, binding: DirectiveBinding) {\n if (!el._permission_data || el._permission_data.action !== binding.value) {\n await processElement(el, binding.value, true);\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}\n\n// Директива vCant - противоположность vCan, показывает элемент только если прав НЕТ\nexport const vCant: ObjectDirective = {\n async mounted(el: CanHTMLElement, binding: DirectiveBinding) {\n await processElement(el, binding.value, false);\n },\n\n async updated(el: CanHTMLElement, binding: DirectiveBinding) {\n if (!el._permission_data || el._permission_data.action !== binding.value) {\n await processElement(el, binding.value, false);\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, inject, InjectionKey } from 'vue'\nimport { PermissionsService, PermissionsOptions } from './services/permissionsService'\nimport { setPermissionsService } from './directives/vCan'\n\nexport const PermissionsKey: InjectionKey<PermissionsService> = Symbol('Permissions')\n\nexport function setupPermissions(options?: PermissionsOptions): PermissionsService {\n const service = new PermissionsService(options);\n // Устанавливаем глобальный сервис для директивы\n setPermissionsService(service);\n return service;\n}\n\nexport const PermissionsPlugin = {\n install(app: App, options?: PermissionsOptions) {\n const permissionsService = setupPermissions(options);\n app.provide(PermissionsKey, permissionsService);\n\n // Добавим сервис в глобальные свойства Vue для доступа откуда угодно\n app.config.globalProperties.$permissions = 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 && !isInitialLoading\" />\n <slot name=\"fallback\" v-else-if=\"!isLoading && !isInitialLoading && !can\" />\n <slot name=\"loading\" v-else-if=\"isLoading || isInitialLoading\" />\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, toRefs, PropType, ref, onMounted } 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 isInitialLoading = ref(true);\n const { can, isLoading, check } = usePermissions(action, { autoCheck: false });\n \n onMounted(async () => {\n await check();\n isInitialLoading.value = false;\n });\n\n return {\n can,\n isLoading,\n isInitialLoading\n };\n }\n});\n</script> ","import { App } from 'vue'\nimport Check from './components/Check.vue'\nimport { usePermissions } from './composables/usePermissions'\nimport { PermissionsPlugin, setupPermissions, usePermissionsService } from './plugin'\nimport { vCan, vCant, setPermissionsService } from './directives/vCan'\n\n// Именованные экспорты\nexport {\n Check,\n usePermissions,\n setupPermissions,\n vCan,\n vCant,\n usePermissionsService,\n setPermissionsService\n}\n\n// Создаем основной объект плагина\nconst plugin = {\n install(app: App, options?: { baseUrl?: string }) {\n // Важно: сначала нужно инициализировать PermissionsPlugin для provide/inject механизма\n app.use(PermissionsPlugin, options)\n\n // Затем регистрируем компонент и директивы\n app.component('Check', Check)\n app.directive('can', vCan)\n app.directive('cant', vCant)\n }\n}\n\n// Экспортируем плагин как по умолчанию\nexport default plugin "],"names":["PermissionsService","options","__publicField","axios","action","allowed","error","globalPermissionsService","permissionsCache","setPermissionsService","service","checkPermission","permissionPromise","processElement","el","showWhenAllowed","originalDisplay","hasPermission","vCan","binding","vCant","PermissionsKey","setupPermissions","PermissionsPlugin","app","permissionsService","usePermissionsService","inject","usePermissions","isAllowed","ref","isLoading","actionValue","computed","err","unwatch","watch","onUnmounted","_sfc_main","defineComponent","props","toRefs","isInitialLoading","can","check","onMounted","_ctx","_renderSlot","_createCommentVNode","plugin","Check"],"mappings":";;;;;AAOO,MAAMA,EAAmB;AAAA,EAK5B,YAAYC,GAA8B;AAJlC,IAAAC,EAAA;AACA,IAAAA,EAAA,mCAAkC,IAAI;AACtC,IAAAA,EAAA;AAGC,SAAA,QAAQC,EAAM,OAAO;AAAA,MACtB,UAASF,KAAA,gBAAAA,EAAS,YAAW;AAAA,IAAA,CAChC,GACI,KAAA,YAAWA,KAAA,gBAAAA,EAAS,aAAY;AAAA,EAAA;AAAA,EAGzC,MAAM,IAAIG,GAAkC;AAExC,QAAI,KAAK,MAAM,IAAIA,CAAM;AACd,aAAA,KAAK,MAAM,IAAIA,CAAM;AAG5B,QAAA;AAKM,YAAAC,KAJW,MAAM,KAAK,MAAM,IAAI,KAAK,UAAU;AAAA,QACjD,QAAQ,EAAE,QAAAD,EAAO;AAAA,MAAA,CACpB,GAEwB,KAAK,WAAW;AAGpC,kBAAA,MAAM,IAAIA,GAAQC,CAAO,GAEvBA;AAAA,aACFC,GAAO;AACZ,qBAAQ,MAAM,iCAAiCF,CAAM,KAAKE,CAAK,GACxD;AAAA,IAAA;AAAA,EACX;AAAA,EAGJ,WAAWF,GAAuB;AAC9B,IAAIA,IACK,KAAA,MAAM,OAAOA,CAAM,IAExB,KAAK,MAAM,MAAM;AAAA,EACrB;AAER;ACrCA,IAAIG,IAAsD;AAG1D,MAAMC,wBAAsD,IAAI;AAGzD,SAASC,EAAsBC,GAAmC;AAC1C,EAAAH,IAAAG;AAC/B;AAGA,eAAeC,EAAgBP,GAAkC;AAC7D,MAAI,CAACG;AACD,mBAAQ,KAAK,0CAA0C,GAChD;AAIX,MAAI,CAACC,EAAiB,IAAIJ,CAAM,GAAG;AAE/B,UAAMQ,IAAoBL,EAAyB,IAAIH,CAAM,EACxD,MAAM,CAASE,OACJ,QAAA,MAAM,8BAA8BA,CAAK,GACjDE,EAAiB,OAAOJ,CAAM,GACvB,GACV;AAEY,IAAAI,EAAA,IAAIJ,GAAQQ,CAAiB;AAAA,EAAA;AAI3C,SAAAJ,EAAiB,IAAIJ,CAAM;AACtC;AAGA,eAAeS,EAAeC,GAAoBV,GAAgBW,GAA0B;AAClF,QAAAC,IAAkBF,EAAG,MAAM;AAGjC,EAAAA,EAAG,mBAAmB;AAAA,IAClB,QAAAV;AAAA,IACA,iBAAAY;AAAA,IACA,mBAAmB;AAAA,EACvB,GAGAF,EAAG,MAAM,UAAU;AAEf,MAAA;AACM,UAAAG,IAAgB,MAAMN,EAAgBP,CAAM;AAGlD,KAAKW,KAAmBE,KAAmB,CAACF,KAAmB,CAACE,OACzDH,EAAA,MAAM,UAAUE,KAAmB,KAG1CF,EAAG,iBAAiB,oBAAoB;AAAA,WACnCR,GAAO;AACJ,YAAA,MAAM,kCAAkCA,CAAK,GAEhDS,MACED,EAAA,MAAM,UAAUE,KAAmB;AAAA,EAC1C;AAER;AAEO,MAAME,IAAwB;AAAA,EACjC,MAAM,QAAQJ,GAAoBK,GAA2B;AACzD,UAAMN,EAAeC,GAAIK,EAAQ,OAAO,EAAI;AAAA,EAChD;AAAA,EAEA,MAAM,QAAQL,GAAoBK,GAA2B;AACzD,KAAI,CAACL,EAAG,oBAAoBA,EAAG,iBAAiB,WAAWK,EAAQ,UAC/D,MAAMN,EAAeC,GAAIK,EAAQ,OAAO,EAAI;AAAA,EAEpD;AAAA,EAEA,UAAUL,GAAoB;AAC1B,IAAIA,EAAG,qBACAA,EAAA,MAAM,UAAUA,EAAG,iBAAiB,iBACvC,OAAOA,EAAG;AAAA,EACd;AAER,GAGaM,IAAyB;AAAA,EAClC,MAAM,QAAQN,GAAoBK,GAA2B;AACzD,UAAMN,EAAeC,GAAIK,EAAQ,OAAO,EAAK;AAAA,EACjD;AAAA,EAEA,MAAM,QAAQL,GAAoBK,GAA2B;AACzD,KAAI,CAACL,EAAG,oBAAoBA,EAAG,iBAAiB,WAAWK,EAAQ,UAC/D,MAAMN,EAAeC,GAAIK,EAAQ,OAAO,EAAK;AAAA,EAErD;AAAA,EAEA,UAAUL,GAAoB;AAC1B,IAAIA,EAAG,qBACAA,EAAA,MAAM,UAAUA,EAAG,iBAAiB,iBACvC,OAAOA,EAAG;AAAA,EACd;AAER,GC/GaO,IAAmD,OAAO,aAAa;AAE7E,SAASC,EAAiBrB,GAAkD;AACzE,QAAAS,IAAU,IAAIV,EAAmBC,CAAO;AAE9C,SAAAQ,EAAsBC,CAAO,GACtBA;AACX;AAEO,MAAMa,IAAoB;AAAA,EAC7B,QAAQC,GAAUvB,GAA8B;AACtC,UAAAwB,IAAqBH,EAAiBrB,CAAO;AAC/C,IAAAuB,EAAA,QAAQH,GAAgBI,CAAkB,GAG1CD,EAAA,OAAO,iBAAiB,eAAeC;AAAA,EAAA;AAEnD;AAEO,SAASC,IAA4C;AAClD,QAAAD,IAAqBE,EAAON,CAAc;AAChD,MAAI,CAACI;AACK,UAAA,IAAI,MAAM,mCAAmC;AAEhD,SAAAA;AACX;ACtBO,SAASG,EAAexB,GAA8BH,IAAiC,IAAI;AAC9F,QAAMwB,IAAqBC,EAAsB,GAC3CG,IAAYC,EAAoB,IAAI,GACpCC,IAAYD,EAAI,EAAK,GACrBxB,IAAQwB,EAAkB,IAAI,GAE9BE,IAAcC,EAAS,MAClB,OAAO7B,KAAW,WAAWA,IAASA,EAAO,KACvD,GAEKO,IAAkB,YAAY;AAC5B,QAACqB,EAAY,OAEjB;AAAA,MAAAD,EAAU,QAAQ,IAClBzB,EAAM,QAAQ;AAEV,UAAA;AACA,QAAAuB,EAAU,QAAQ,MAAMJ,EAAmB,IAAIO,EAAY,KAAK;AAAA,eAC3DE,GAAK;AACJ,QAAA5B,EAAA,QAAQ4B,aAAe,QAAQA,IAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,GAChEL,EAAU,QAAQ;AAAA,MAAA,UACpB;AACE,QAAAE,EAAU,QAAQ;AAAA,MAAA;AAAA;AAAA,EAE1B;AAQI,MALA9B,EAAQ,cAAc,MACNU,EAAA,GAIhB,OAAOP,KAAW,UAAU;AACtB,UAAA+B,IAAUC,EAAMhC,GAAQ,MAAM;AAChB,MAAAO,EAAA;AAAA,IAAA,CACnB;AAED,IAAA0B,EAAY,MAAM;AACN,MAAAF,EAAA;AAAA,IAAA,CACX;AAAA,EAAA;AAGE,SAAA;AAAA,IACH,WAAAN;AAAA,IACA,WAAAE;AAAA,IACA,OAAAzB;AAAA,IACA,OAAOK;AAAA,IACP,KAAKsB,EAAS,MAAMJ,EAAU,UAAU,EAAI;AAAA,EAChD;AACJ;AC9CA,MAAAS,IAAeC,EAAgB;AAAA,EAC7B,MAAM;AAAA,EACN,OAAO;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,EAEb;AAAA,EACA,MAAMC,GAAO;AACX,UAAM,EAAE,QAAApC,EAAA,IAAWqC,EAAOD,CAAK,GACzBE,IAAmBZ,EAAI,EAAI,GAC3B,EAAE,KAAAa,GAAK,WAAAZ,GAAW,OAAAa,EAAM,IAAIhB,EAAexB,GAAQ,EAAE,WAAW,IAAO;AAE7E,WAAAyC,EAAU,YAAY;AACpB,YAAMD,EAAM,GACZF,EAAiB,QAAQ;AAAA,IAAA,CAC1B,GAEM;AAAA,MACL,KAAAC;AAAA,MACA,WAAAZ;AAAA,MACA,kBAAAW;AAAA,IACF;AAAA,EAAA;AAEJ,CAAC;;;;;;;AArCa,SAAAI,EAAA,OAAG,CAAKA,EAApB,mBAAAC,EAAwCD,EAD1C,QAAA,WAAA,EAAA,KAAA,EAAA,CAAA,IAAA,CAEoCA,eAAS,CAAKA,EAAA,oBAAgB,CAAKA,EAAA,MAArEC,EAA4ED,EAF9E,QAAA,YAAA,EAAA,KAAA,EAAA,CAAA,IAGkCA,EAAa,aAAAA,EAAA,mBAA7CC,EAAiED,EAHnE,QAAA,WAAA,EAAA,KAAA,EAAA,CAAA,IAAAE,EAAA,IAAA,EAAA;;iDCkBMC,IAAS;AAAA,EACX,QAAQzB,GAAUvB,GAAgC;AAE1C,IAAAuB,EAAA,IAAID,GAAmBtB,CAAO,GAG9BuB,EAAA,UAAU,SAAS0B,CAAK,GACxB1B,EAAA,UAAU,OAAON,CAAI,GACrBM,EAAA,UAAU,QAAQJ,CAAK;AAAA,EAAA;AAEnC;"}
@@ -1,2 +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,t){"use strict";var E=Object.defineProperty;var b=(n,i,t)=>i in n?E(n,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[i]=t;var u=(n,i,t)=>b(n,typeof i!="symbol"?i+"":i,t);class k{constructor(s){u(this,"axios");u(this,"cache",new Map);u(this,"endpoint");this.axios=t.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()}}let l=null;function f(e){l=e}const p={async mounted(e,s){const r=e.style.display;if(e._permission_data={action:s.value,originalDisplay:r,permissionChecked:!1},e.style.display="none",!l){console.warn("Permissions service not initialized yet. Element will remain hidden.");return}try{await l.can(s.value)&&(e.style.display=r||""),e._permission_data.permissionChecked=!0}catch(a){console.error("Error checking permission:",a)}},async updated(e,s){var r;if(!e._permission_data||e._permission_data.action!==s.value){const a=((r=e._permission_data)==null?void 0:r.originalDisplay)||e.style.display||"";if(e._permission_data={action:s.value,originalDisplay:a,permissionChecked:!1},e.style.display="none",!l){console.warn("Permissions service not initialized yet. Element will remain hidden.");return}try{await l.can(s.value)&&(e.style.display=e._permission_data.originalDisplay||""),e._permission_data.permissionChecked=!0}catch(o){console.error("Error checking permission:",o)}}},unmounted(e){e._permission_data&&(e.style.display=e._permission_data.originalDisplay,delete e._permission_data)}},h=Symbol("Permissions");function y(e){const s=new k(e);return f(s),s}const w={install(e,s){const r=y(s);e.provide(h,r),e.config.globalProperties.$permissions=r}};function g(){const e=i.inject(h);if(!e)throw new Error("Permissions plugin not installed!");return e}function v(e,s={}){const r=g(),a=i.ref(null),o=i.ref(!1),c=i.ref(null),_=i.computed(()=>typeof e=="string"?e:e.value),m=async()=>{if(_.value){o.value=!0,c.value=null;try{a.value=await r.can(_.value)}catch(d){c.value=d instanceof Error?d:new Error(String(d)),a.value=!1}finally{o.value=!1}}};if(s.autoCheck!==!1&&m(),typeof e!="string"){const d=i.watch(e,()=>{m()});i.onUnmounted(()=>{d()})}return{isAllowed:a,isLoading:o,error:c,check:m,can:i.computed(()=>a.value===!0)}}const S=i.defineComponent({name:"Check",props:{action:{type:String,required:!0},fallback:{type:Boolean,default:!1}},setup(e){const{action:s}=i.toRefs(e),r=i.ref(!0),{can:a,isLoading:o,check:c}=v(s,{autoCheck:!1});return i.onMounted(async()=>{await c(),r.value=!1}),{can:a,isLoading:o,isInitialLoading:r}}}),C=(e,s)=>{const r=e.__vccOpts||e;for(const[a,o]of s)r[a]=o;return r};function L(e,s,r,a,o,c){return e.can&&!e.isInitialLoading?i.renderSlot(e.$slots,"default",{key:0}):!e.isLoading&&!e.isInitialLoading&&!e.can?i.renderSlot(e.$slots,"fallback",{key:1}):e.isLoading||e.isInitialLoading?i.renderSlot(e.$slots,"loading",{key:2}):i.createCommentVNode("",!0)}const P=C(S,[["render",L]]),$={install(e,s){e.use(w,s),e.component("Check",P),e.directive("can",p)}};n.Check=P,n.default=$,n.setPermissionsService=f,n.setupPermissions=y,n.usePermissions=v,n.usePermissionsService=g,n.vCan=p,Object.defineProperties(n,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
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 j=Object.defineProperty;var q=(n,i,o)=>i in n?j(n,i,{enumerable:!0,configurable:!0,writable:!0,value:o}):n[i]=o;var f=(n,i,o)=>q(n,typeof i!="symbol"?i+"":i,o);class C{constructor(s){f(this,"axios");f(this,"cache",new Map);f(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()}}let m=null;const u=new Map;function h(e){m=e}async function L(e){if(!m)return console.warn("Permissions service not initialized yet."),!1;if(!u.has(e)){const s=m.can(e).catch(r=>(console.error("Error checking permission:",r),u.delete(e),!1));u.set(e,s)}return u.get(e)}async function d(e,s,r){const a=e.style.display;e._permission_data={action:s,originalDisplay:a,permissionChecked:!1},e.style.display="none";try{const t=await L(s);(r&&t||!r&&!t)&&(e.style.display=a||""),e._permission_data.permissionChecked=!0}catch(t){console.error("Error in directive processing:",t),r||(e.style.display=a||"")}}const y={async mounted(e,s){await d(e,s.value,!0)},async updated(e,s){(!e._permission_data||e._permission_data.action!==s.value)&&await d(e,s.value,!0)},unmounted(e){e._permission_data&&(e.style.display=e._permission_data.originalDisplay,delete e._permission_data)}},v={async mounted(e,s){await d(e,s.value,!1)},async updated(e,s){(!e._permission_data||e._permission_data.action!==s.value)&&await d(e,s.value,!1)},unmounted(e){e._permission_data&&(e.style.display=e._permission_data.originalDisplay,delete e._permission_data)}},g=Symbol("Permissions");function _(e){const s=new C(e);return h(s),s}const $={install(e,s){const r=_(s);e.provide(g,r),e.config.globalProperties.$permissions=r}};function P(){const e=i.inject(g);if(!e)throw new Error("Permissions plugin not installed!");return e}function k(e,s={}){const r=P(),a=i.ref(null),t=i.ref(!1),c=i.ref(null),w=i.computed(()=>typeof e=="string"?e:e.value),p=async()=>{if(w.value){t.value=!0,c.value=null;try{a.value=await r.can(w.value)}catch(l){c.value=l instanceof Error?l:new Error(String(l)),a.value=!1}finally{t.value=!1}}};if(s.autoCheck!==!1&&p(),typeof e!="string"){const l=i.watch(e,()=>{p()});i.onUnmounted(()=>{l()})}return{isAllowed:a,isLoading:t,error:c,check:p,can:i.computed(()=>a.value===!0)}}const b=i.defineComponent({name:"Check",props:{action:{type:String,required:!0},fallback:{type:Boolean,default:!1}},setup(e){const{action:s}=i.toRefs(e),r=i.ref(!0),{can:a,isLoading:t,check:c}=k(s,{autoCheck:!1});return i.onMounted(async()=>{await c(),r.value=!1}),{can:a,isLoading:t,isInitialLoading:r}}}),E=(e,s)=>{const r=e.__vccOpts||e;for(const[a,t]of s)r[a]=t;return r};function M(e,s,r,a,t,c){return e.can&&!e.isInitialLoading?i.renderSlot(e.$slots,"default",{key:0}):!e.isLoading&&!e.isInitialLoading&&!e.can?i.renderSlot(e.$slots,"fallback",{key:1}):e.isLoading||e.isInitialLoading?i.renderSlot(e.$slots,"loading",{key:2}):i.createCommentVNode("",!0)}const S=E(b,[["render",M]]),I={install(e,s){e.use($,s),e.component("Check",S),e.directive("can",y),e.directive("cant",v)}};n.Check=S,n.default=I,n.setPermissionsService=h,n.setupPermissions=_,n.usePermissions=k,n.usePermissionsService=P,n.vCan=y,n.vCant=v,Object.defineProperties(n,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
2
2
  //# sourceMappingURL=locator-ars-lib.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"locator-ars-lib.umd.js","sources":["../src/services/permissionsService.ts","../src/directives/vCan.ts","../src/plugin.ts","../src/composables/usePermissions.ts","../src/components/Check.vue","../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 { ObjectDirective, DirectiveBinding } from 'vue'\nimport { PermissionsService } from '../services/permissionsService'\n\ninterface CanHTMLElement extends HTMLElement {\n _permission_data?: {\n action: string\n originalDisplay: string\n permissionChecked?: boolean\n }\n}\n\n// Глобальный сервис проверки прав\nlet globalPermissionsService: PermissionsService | null = null;\n\n// Функция для установки экземпляра сервиса (будет вызываться при инициализации плагина)\nexport function setPermissionsService(service: PermissionsService): void {\n globalPermissionsService = service;\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 permissionChecked: false\n };\n\n // Скрываем элемент изначально до проверки прав\n el.style.display = 'none';\n\n if (!globalPermissionsService) {\n console.warn('Permissions service not initialized yet. Element will remain hidden.');\n return;\n }\n\n try {\n const hasPermission = await globalPermissionsService.can(binding.value);\n\n if (hasPermission) {\n // Показываем элемент только если есть права\n el.style.display = originalDisplay || '';\n }\n\n el._permission_data.permissionChecked = true;\n } catch (error) {\n console.error('Error checking permission:', error);\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 const originalDisplay = el._permission_data?.originalDisplay || el.style.display || '';\n\n el._permission_data = {\n action: binding.value,\n originalDisplay,\n permissionChecked: false\n };\n\n // Скрываем элемент при обновлении до проверки прав\n el.style.display = 'none';\n\n if (!globalPermissionsService) {\n console.warn('Permissions service not initialized yet. Element will remain hidden.');\n return;\n }\n\n try {\n const hasPermission = await globalPermissionsService.can(binding.value);\n\n if (hasPermission) {\n el.style.display = el._permission_data.originalDisplay || '';\n }\n\n el._permission_data.permissionChecked = true;\n } catch (error) {\n console.error('Error checking permission:', error);\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, inject, InjectionKey } from 'vue'\nimport { PermissionsService, PermissionsOptions } from './services/permissionsService'\nimport { setPermissionsService } from './directives/vCan'\n\nexport const PermissionsKey: InjectionKey<PermissionsService> = Symbol('Permissions')\n\nexport function setupPermissions(options?: PermissionsOptions): PermissionsService {\n const service = new PermissionsService(options);\n // Устанавливаем глобальный сервис для директивы\n setPermissionsService(service);\n return service;\n}\n\nexport const PermissionsPlugin = {\n install(app: App, options?: PermissionsOptions) {\n const permissionsService = setupPermissions(options);\n app.provide(PermissionsKey, permissionsService);\n\n // Добавим сервис в глобальные свойства Vue для доступа откуда угодно\n app.config.globalProperties.$permissions = 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 && !isInitialLoading\" />\n <slot name=\"fallback\" v-else-if=\"!isLoading && !isInitialLoading && !can\" />\n <slot name=\"loading\" v-else-if=\"isLoading || isInitialLoading\" />\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, toRefs, PropType, ref, onMounted } 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 isInitialLoading = ref(true);\n const { can, isLoading, check } = usePermissions(action, { autoCheck: false });\n \n onMounted(async () => {\n await check();\n isInitialLoading.value = false;\n });\n\n return {\n can,\n isLoading,\n isInitialLoading\n };\n }\n});\n</script> ","import { App } from 'vue'\nimport Check from './components/Check.vue'\nimport { usePermissions } from './composables/usePermissions'\nimport { PermissionsPlugin, setupPermissions, usePermissionsService } from './plugin'\nimport { vCan, setPermissionsService } from './directives/vCan'\n\n// Именованные экспорты\nexport {\n Check,\n usePermissions,\n setupPermissions,\n vCan,\n usePermissionsService,\n setPermissionsService\n}\n\n// Создаем основной объект плагина\nconst plugin = {\n install(app: App, options?: { baseUrl?: string }) {\n // Важно: сначала нужно инициализировать PermissionsPlugin для provide/inject механизма\n app.use(PermissionsPlugin, options)\n\n // Затем регистрируем компонент и директиву\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","globalPermissionsService","setPermissionsService","service","vCan","el","binding","originalDisplay","_a","PermissionsKey","setupPermissions","PermissionsPlugin","app","permissionsService","usePermissionsService","inject","usePermissions","isAllowed","ref","isLoading","actionValue","computed","checkPermission","err","unwatch","watch","onUnmounted","_sfc_main","defineComponent","props","toRefs","isInitialLoading","can","check","onMounted","_ctx","_renderSlot","_createCommentVNode","plugin","Check"],"mappings":"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"}
1
+ {"version":3,"file":"locator-ars-lib.umd.js","sources":["../src/services/permissionsService.ts","../src/directives/vCan.ts","../src/plugin.ts","../src/composables/usePermissions.ts","../src/components/Check.vue","../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 { ObjectDirective, DirectiveBinding } from 'vue'\nimport { PermissionsService } from '../services/permissionsService'\n\ninterface CanHTMLElement extends HTMLElement {\n _permission_data?: {\n action: string\n originalDisplay: string\n permissionChecked?: boolean\n }\n}\n\n// Глобальный сервис проверки прав\nlet globalPermissionsService: PermissionsService | null = null;\n\n// Кэш результатов проверки прав для избежания дублирования запросов\nconst permissionsCache: Map<string, Promise<boolean>> = new Map();\n\n// Функция для установки экземпляра сервиса (будет вызываться при инициализации плагина)\nexport function setPermissionsService(service: PermissionsService): void {\n globalPermissionsService = service;\n}\n\n// Общая функция проверки прав для обеих директив\nasync function checkPermission(action: string): Promise<boolean> {\n if (!globalPermissionsService) {\n console.warn('Permissions service not initialized yet.');\n return false;\n }\n\n // Проверяем есть ли запрос с таким же action уже в процессе выполнения\n if (!permissionsCache.has(action)) {\n // Создаем Promise для проверки прав и сохраняем в кэш\n const permissionPromise = globalPermissionsService.can(action)\n .catch(error => {\n console.error('Error checking permission:', error);\n permissionsCache.delete(action);\n return false;\n });\n\n permissionsCache.set(action, permissionPromise);\n }\n\n // Возвращаем результат из кэша (либо готовый, либо ожидающий Promise)\n return permissionsCache.get(action) as Promise<boolean>;\n}\n\n// Общая логика для обработки элементов, применяемая обеими директивами\nasync function processElement(el: CanHTMLElement, action: string, showWhenAllowed: boolean) {\n const originalDisplay = el.style.display;\n\n // Store action and original display for updates\n el._permission_data = {\n action,\n originalDisplay,\n permissionChecked: false\n };\n\n // Скрываем элемент изначально до проверки прав\n el.style.display = 'none';\n\n try {\n const hasPermission = await checkPermission(action);\n\n // Показываем элемент в зависимости от режима и результата проверки\n if ((showWhenAllowed && hasPermission) || (!showWhenAllowed && !hasPermission)) {\n el.style.display = originalDisplay || '';\n }\n\n el._permission_data.permissionChecked = true;\n } catch (error) {\n console.error('Error in directive processing:', error);\n // При ошибке для v-cant показываем элемент\n if (!showWhenAllowed) {\n el.style.display = originalDisplay || '';\n }\n }\n}\n\nexport const vCan: ObjectDirective = {\n async mounted(el: CanHTMLElement, binding: DirectiveBinding) {\n await processElement(el, binding.value, true);\n },\n\n async updated(el: CanHTMLElement, binding: DirectiveBinding) {\n if (!el._permission_data || el._permission_data.action !== binding.value) {\n await processElement(el, binding.value, true);\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}\n\n// Директива vCant - противоположность vCan, показывает элемент только если прав НЕТ\nexport const vCant: ObjectDirective = {\n async mounted(el: CanHTMLElement, binding: DirectiveBinding) {\n await processElement(el, binding.value, false);\n },\n\n async updated(el: CanHTMLElement, binding: DirectiveBinding) {\n if (!el._permission_data || el._permission_data.action !== binding.value) {\n await processElement(el, binding.value, false);\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, inject, InjectionKey } from 'vue'\nimport { PermissionsService, PermissionsOptions } from './services/permissionsService'\nimport { setPermissionsService } from './directives/vCan'\n\nexport const PermissionsKey: InjectionKey<PermissionsService> = Symbol('Permissions')\n\nexport function setupPermissions(options?: PermissionsOptions): PermissionsService {\n const service = new PermissionsService(options);\n // Устанавливаем глобальный сервис для директивы\n setPermissionsService(service);\n return service;\n}\n\nexport const PermissionsPlugin = {\n install(app: App, options?: PermissionsOptions) {\n const permissionsService = setupPermissions(options);\n app.provide(PermissionsKey, permissionsService);\n\n // Добавим сервис в глобальные свойства Vue для доступа откуда угодно\n app.config.globalProperties.$permissions = 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 && !isInitialLoading\" />\n <slot name=\"fallback\" v-else-if=\"!isLoading && !isInitialLoading && !can\" />\n <slot name=\"loading\" v-else-if=\"isLoading || isInitialLoading\" />\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent, toRefs, PropType, ref, onMounted } 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 isInitialLoading = ref(true);\n const { can, isLoading, check } = usePermissions(action, { autoCheck: false });\n \n onMounted(async () => {\n await check();\n isInitialLoading.value = false;\n });\n\n return {\n can,\n isLoading,\n isInitialLoading\n };\n }\n});\n</script> ","import { App } from 'vue'\nimport Check from './components/Check.vue'\nimport { usePermissions } from './composables/usePermissions'\nimport { PermissionsPlugin, setupPermissions, usePermissionsService } from './plugin'\nimport { vCan, vCant, setPermissionsService } from './directives/vCan'\n\n// Именованные экспорты\nexport {\n Check,\n usePermissions,\n setupPermissions,\n vCan,\n vCant,\n usePermissionsService,\n setPermissionsService\n}\n\n// Создаем основной объект плагина\nconst plugin = {\n install(app: App, options?: { baseUrl?: string }) {\n // Важно: сначала нужно инициализировать PermissionsPlugin для provide/inject механизма\n app.use(PermissionsPlugin, options)\n\n // Затем регистрируем компонент и директивы\n app.component('Check', Check)\n app.directive('can', vCan)\n app.directive('cant', vCant)\n }\n}\n\n// Экспортируем плагин как по умолчанию\nexport default plugin "],"names":["PermissionsService","options","__publicField","axios","action","allowed","error","globalPermissionsService","permissionsCache","setPermissionsService","service","checkPermission","permissionPromise","processElement","el","showWhenAllowed","originalDisplay","hasPermission","vCan","binding","vCant","PermissionsKey","setupPermissions","PermissionsPlugin","app","permissionsService","usePermissionsService","inject","usePermissions","isAllowed","ref","isLoading","actionValue","computed","err","unwatch","watch","onUnmounted","_sfc_main","defineComponent","props","toRefs","isInitialLoading","can","check","onMounted","_ctx","_renderSlot","_createCommentVNode","plugin","Check"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locator-ars-lib",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Permissions library for Vue 3 applications",
5
5
  "type": "module",
6
6
  "main": "./dist/locator-ars-lib.umd.js",