com-angel-authorization 1.0.0

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.
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/vue/index.ts
21
+ var vue_exports = {};
22
+ __export(vue_exports, {
23
+ Can: () => Can,
24
+ PERMISSION_STORE_KEY: () => PERMISSION_STORE_KEY,
25
+ PermissionStore: () => import_core2.PermissionStore,
26
+ createPermissionPlugin: () => createPermissionPlugin,
27
+ createPermissionStore: () => import_core2.createPermissionStore,
28
+ createVPermission: () => createVPermission,
29
+ useHasPermission: () => useHasPermission,
30
+ useHasRole: () => useHasRole,
31
+ usePermission: () => usePermission
32
+ });
33
+ module.exports = __toCommonJS(vue_exports);
34
+
35
+ // src/vue/plugin.ts
36
+ var import_vue = require("vue");
37
+ var import_core = require("../core");
38
+
39
+ // src/vue/directive.ts
40
+ function parseBinding(binding) {
41
+ const value = binding.value;
42
+ const arg = binding.arg;
43
+ if (value && typeof value === "object" && !Array.isArray(value)) {
44
+ return {
45
+ permission: value.permission,
46
+ role: value.role,
47
+ mode: value.mode ?? (arg === "all" ? "all" : "any"),
48
+ combine: value.combine ?? "and",
49
+ display: value.display
50
+ };
51
+ }
52
+ if (arg === "role") {
53
+ return {
54
+ role: value,
55
+ mode: binding.modifiers.all ? "all" : "any",
56
+ combine: "and"
57
+ };
58
+ }
59
+ return {
60
+ permission: value,
61
+ mode: arg === "all" || binding.modifiers.all ? "all" : "any",
62
+ combine: "and"
63
+ };
64
+ }
65
+ function isAllowed(store, binding) {
66
+ const { permission, role, mode, combine } = parseBinding(binding);
67
+ const options = { mode };
68
+ const hasPermCheck = permission !== void 0;
69
+ const hasRoleCheck = role !== void 0;
70
+ if (!hasPermCheck && !hasRoleCheck) return true;
71
+ const permOk = hasPermCheck ? store.hasPermission(permission, options) : true;
72
+ const roleOk = hasRoleCheck ? store.hasRole(role, options) : true;
73
+ if (hasPermCheck && hasRoleCheck) {
74
+ return combine === "or" ? permOk || roleOk : permOk && roleOk;
75
+ }
76
+ return hasPermCheck ? permOk : roleOk;
77
+ }
78
+ function applyVisibility(el, allowed, display) {
79
+ if (el.__angelPermissionDisplay === void 0) {
80
+ el.__angelPermissionDisplay = el.style.display;
81
+ }
82
+ if (allowed) {
83
+ el.style.display = display ?? el.__angelPermissionDisplay ?? "";
84
+ el.removeAttribute("aria-hidden");
85
+ } else {
86
+ el.style.display = "none";
87
+ el.setAttribute("aria-hidden", "true");
88
+ }
89
+ }
90
+ function createVPermission(store) {
91
+ return {
92
+ mounted(el, binding) {
93
+ const update = () => {
94
+ const { display } = parseBinding(binding);
95
+ applyVisibility(el, isAllowed(store, binding), display);
96
+ };
97
+ update();
98
+ el.__angelPermissionUnsubscribe = store.subscribe(update);
99
+ },
100
+ updated(el, binding) {
101
+ const { display } = parseBinding(binding);
102
+ applyVisibility(el, isAllowed(store, binding), display);
103
+ },
104
+ unmounted(el) {
105
+ el.__angelPermissionUnsubscribe?.();
106
+ delete el.__angelPermissionUnsubscribe;
107
+ delete el.__angelPermissionDisplay;
108
+ }
109
+ };
110
+ }
111
+
112
+ // src/vue/plugin.ts
113
+ var PERMISSION_STORE_KEY = /* @__PURE__ */ Symbol(
114
+ "angel-authorization-store"
115
+ );
116
+ function createPermissionPlugin(options = {}) {
117
+ const store = options.store ?? (0, import_core.createPermissionStore)(options.initialState);
118
+ const directiveName = options.directiveName ?? "permission";
119
+ const plugin = {
120
+ store,
121
+ install(app) {
122
+ app.provide(PERMISSION_STORE_KEY, store);
123
+ app.directive(directiveName, createVPermission(store));
124
+ app.config.globalProperties.$permission = store;
125
+ app.config.globalProperties.$can = (codes, opts) => store.can(codes, opts);
126
+ app.config.globalProperties.$hasRole = (codes, opts) => store.hasRole(codes, opts);
127
+ }
128
+ };
129
+ return plugin;
130
+ }
131
+ function resolveStore(store) {
132
+ const injected = store ?? (0, import_vue.inject)(PERMISSION_STORE_KEY, null);
133
+ if (!injected) {
134
+ throw new Error(
135
+ "[com-angel-authorization/vue] Permission store not found. Did you call app.use(createPermissionPlugin())?"
136
+ );
137
+ }
138
+ return injected;
139
+ }
140
+ function usePermission(store) {
141
+ const permissionStore = resolveStore(store);
142
+ const state = (0, import_vue.shallowRef)(permissionStore.getState());
143
+ const unsubscribe = permissionStore.subscribe((next) => {
144
+ state.value = next;
145
+ });
146
+ (0, import_vue.onScopeDispose)(unsubscribe);
147
+ return {
148
+ permissions: (0, import_vue.computed)(() => state.value.permissions),
149
+ roles: (0, import_vue.computed)(() => state.value.roles),
150
+ isSuperAdmin: (0, import_vue.computed)(() => Boolean(state.value.isSuperAdmin)),
151
+ hasPermission: (codes, options) => permissionStore.hasPermission(codes, options),
152
+ hasRole: (codes, options) => permissionStore.hasRole(codes, options),
153
+ can: (codes, options) => permissionStore.can(codes, options),
154
+ setPermissions: permissionStore.setPermissions.bind(permissionStore),
155
+ setRoles: permissionStore.setRoles.bind(permissionStore),
156
+ setSuperAdmin: permissionStore.setSuperAdmin.bind(permissionStore),
157
+ hydrate: permissionStore.hydrate.bind(permissionStore),
158
+ clear: permissionStore.clear.bind(permissionStore),
159
+ store: permissionStore
160
+ };
161
+ }
162
+ function useHasPermission(codes, options, store) {
163
+ const { permissions, isSuperAdmin, hasPermission } = usePermission(store);
164
+ return (0, import_vue.computed)(() => {
165
+ void permissions.value;
166
+ void isSuperAdmin.value;
167
+ return hasPermission(codes, options);
168
+ });
169
+ }
170
+ function useHasRole(codes, options, store) {
171
+ const { roles, isSuperAdmin, hasRole } = usePermission(store);
172
+ return (0, import_vue.computed)(() => {
173
+ void roles.value;
174
+ void isSuperAdmin.value;
175
+ return hasRole(codes, options);
176
+ });
177
+ }
178
+
179
+ // src/vue/Can.ts
180
+ var import_vue2 = require("vue");
181
+ var Can = (0, import_vue2.defineComponent)({
182
+ name: "Can",
183
+ props: {
184
+ permission: {
185
+ type: [String, Array],
186
+ default: void 0
187
+ },
188
+ role: {
189
+ type: [String, Array],
190
+ default: void 0
191
+ },
192
+ mode: {
193
+ type: String,
194
+ default: "any"
195
+ },
196
+ combine: {
197
+ type: String,
198
+ default: "and"
199
+ }
200
+ },
201
+ setup(props, { slots }) {
202
+ const { hasPermission, hasRole, permissions, roles, isSuperAdmin } = usePermission();
203
+ const allowed = (0, import_vue2.computed)(() => {
204
+ void permissions.value;
205
+ void roles.value;
206
+ void isSuperAdmin.value;
207
+ const hasPermCheck = props.permission !== void 0;
208
+ const hasRoleCheck = props.role !== void 0;
209
+ if (!hasPermCheck && !hasRoleCheck) return true;
210
+ const options = { mode: props.mode };
211
+ const permOk = hasPermCheck ? hasPermission(props.permission, options) : true;
212
+ const roleOk = hasRoleCheck ? hasRole(props.role, options) : true;
213
+ if (hasPermCheck && hasRoleCheck) {
214
+ return props.combine === "or" ? permOk || roleOk : permOk && roleOk;
215
+ }
216
+ return hasPermCheck ? permOk : roleOk;
217
+ });
218
+ return () => {
219
+ if (allowed.value) {
220
+ return slots.default?.();
221
+ }
222
+ return slots.fallback?.() ?? null;
223
+ };
224
+ }
225
+ });
226
+
227
+ // src/vue/index.ts
228
+ var import_core2 = require("../core");
229
+ // Annotate the CommonJS export names for ESM import in node:
230
+ 0 && (module.exports = {
231
+ Can,
232
+ PERMISSION_STORE_KEY,
233
+ PermissionStore,
234
+ createPermissionPlugin,
235
+ createPermissionStore,
236
+ createVPermission,
237
+ useHasPermission,
238
+ useHasRole,
239
+ usePermission
240
+ });
241
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/vue/index.ts","../../src/vue/plugin.ts","../../src/vue/directive.ts","../../src/vue/Can.ts"],"sourcesContent":["export {\n createPermissionPlugin,\n usePermission,\n useHasPermission,\n useHasRole,\n PERMISSION_STORE_KEY,\n} from './plugin';\nexport type { PermissionPluginOptions, UsePermissionResult } from './plugin';\n\nexport { createVPermission } from './directive';\nexport type { PermissionDirectiveValue } from './directive';\n\nexport { Can } from './Can';\n\nexport type {\n CheckOptions,\n MatchMode,\n PermissionChecker,\n PermissionCode,\n PermissionListener,\n PermissionState,\n RoleCode,\n} from '../core';\n\nexport { PermissionStore, createPermissionStore } from '../core';\n","import {\n computed,\n inject,\n onScopeDispose,\n shallowRef,\n type App,\n type ComputedRef,\n type InjectionKey,\n type Plugin,\n} from 'vue';\nimport {\n createPermissionStore,\n type CheckOptions,\n type PermissionCode,\n type PermissionState,\n type PermissionStore,\n type RoleCode,\n} from '../core';\nimport { createVPermission } from './directive';\n\nexport const PERMISSION_STORE_KEY: InjectionKey<PermissionStore> = Symbol(\n 'angel-authorization-store',\n);\n\nexport interface PermissionPluginOptions {\n /** Pass an existing store to share across apps. */\n store?: PermissionStore;\n /** Initial state when the plugin creates its own store. */\n initialState?: Partial<PermissionState>;\n /** Custom directive name. Default: `permission` → `v-permission`. */\n directiveName?: string;\n}\n\nexport function createPermissionPlugin(\n options: PermissionPluginOptions = {},\n): Plugin & { store: PermissionStore } {\n const store = options.store ?? createPermissionStore(options.initialState);\n const directiveName = options.directiveName ?? 'permission';\n\n const plugin: Plugin & { store: PermissionStore } = {\n store,\n install(app: App) {\n app.provide(PERMISSION_STORE_KEY, store);\n app.directive(directiveName, createVPermission(store));\n app.config.globalProperties.$permission = store;\n app.config.globalProperties.$can = (\n codes: PermissionCode | PermissionCode[],\n opts?: CheckOptions,\n ) => store.can(codes, opts);\n app.config.globalProperties.$hasRole = (\n codes: RoleCode | RoleCode[],\n opts?: CheckOptions,\n ) => store.hasRole(codes, opts);\n },\n };\n\n return plugin;\n}\n\nfunction resolveStore(store?: PermissionStore): PermissionStore {\n const injected = store ?? inject(PERMISSION_STORE_KEY, null);\n if (!injected) {\n throw new Error(\n '[com-angel-authorization/vue] Permission store not found. Did you call app.use(createPermissionPlugin())?',\n );\n }\n return injected;\n}\n\nexport interface UsePermissionResult {\n permissions: ComputedRef<PermissionCode[]>;\n roles: ComputedRef<RoleCode[]>;\n isSuperAdmin: ComputedRef<boolean>;\n hasPermission: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;\n hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;\n can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;\n setPermissions: (permissions: PermissionCode[]) => void;\n setRoles: (roles: RoleCode[]) => void;\n setSuperAdmin: (isSuperAdmin: boolean) => void;\n hydrate: (payload: Partial<PermissionState>) => void;\n clear: () => void;\n store: PermissionStore;\n}\n\n/**\n * Reactive permission API for Vue 3 Composition API.\n */\nexport function usePermission(store?: PermissionStore): UsePermissionResult {\n const permissionStore = resolveStore(store);\n const state = shallowRef<PermissionState>(permissionStore.getState());\n\n const unsubscribe = permissionStore.subscribe((next) => {\n state.value = next;\n });\n onScopeDispose(unsubscribe);\n\n return {\n permissions: computed(() => state.value.permissions),\n roles: computed(() => state.value.roles),\n isSuperAdmin: computed(() => Boolean(state.value.isSuperAdmin)),\n hasPermission: (codes, options) => permissionStore.hasPermission(codes, options),\n hasRole: (codes, options) => permissionStore.hasRole(codes, options),\n can: (codes, options) => permissionStore.can(codes, options),\n setPermissions: permissionStore.setPermissions.bind(permissionStore),\n setRoles: permissionStore.setRoles.bind(permissionStore),\n setSuperAdmin: permissionStore.setSuperAdmin.bind(permissionStore),\n hydrate: permissionStore.hydrate.bind(permissionStore),\n clear: permissionStore.clear.bind(permissionStore),\n store: permissionStore,\n };\n}\n\nexport function useHasPermission(\n codes: PermissionCode | PermissionCode[],\n options?: CheckOptions,\n store?: PermissionStore,\n) {\n const { permissions, isSuperAdmin, hasPermission } = usePermission(store);\n return computed(() => {\n void permissions.value;\n void isSuperAdmin.value;\n return hasPermission(codes, options);\n });\n}\n\nexport function useHasRole(\n codes: RoleCode | RoleCode[],\n options?: CheckOptions,\n store?: PermissionStore,\n) {\n const { roles, isSuperAdmin, hasRole } = usePermission(store);\n return computed(() => {\n void roles.value;\n void isSuperAdmin.value;\n return hasRole(codes, options);\n });\n}\n\ndeclare module 'vue' {\n interface ComponentCustomProperties {\n $permission: PermissionStore;\n $can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;\n $hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;\n }\n}\n","import type { Directive, DirectiveBinding } from 'vue';\nimport type { CheckOptions, MatchMode, PermissionCode, PermissionStore, RoleCode } from '../core';\n\nexport type PermissionDirectiveValue =\n | PermissionCode\n | PermissionCode[]\n | {\n permission?: PermissionCode | PermissionCode[];\n role?: RoleCode | RoleCode[];\n mode?: MatchMode;\n /** When both permission and role are set. Default: `and`. */\n combine?: 'and' | 'or';\n /** CSS display value when allowed. Default: restores original display. */\n display?: string;\n };\n\nfunction parseBinding(binding: DirectiveBinding<PermissionDirectiveValue>): {\n permission?: PermissionCode | PermissionCode[];\n role?: RoleCode | RoleCode[];\n mode?: MatchMode;\n combine: 'and' | 'or';\n display?: string;\n} {\n const value = binding.value;\n const arg = binding.arg;\n\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return {\n permission: value.permission,\n role: value.role,\n mode: value.mode ?? (arg === 'all' ? 'all' : 'any'),\n combine: value.combine ?? 'and',\n display: value.display,\n };\n }\n\n if (arg === 'role') {\n return {\n role: value as RoleCode | RoleCode[],\n mode: binding.modifiers.all ? 'all' : 'any',\n combine: 'and',\n };\n }\n\n return {\n permission: value as PermissionCode | PermissionCode[],\n mode: arg === 'all' || binding.modifiers.all ? 'all' : 'any',\n combine: 'and',\n };\n}\n\nfunction isAllowed(\n store: PermissionStore,\n binding: DirectiveBinding<PermissionDirectiveValue>,\n): boolean {\n const { permission, role, mode, combine } = parseBinding(binding);\n const options: CheckOptions = { mode };\n\n const hasPermCheck = permission !== undefined;\n const hasRoleCheck = role !== undefined;\n\n if (!hasPermCheck && !hasRoleCheck) return true;\n\n const permOk = hasPermCheck ? store.hasPermission(permission!, options) : true;\n const roleOk = hasRoleCheck ? store.hasRole(role!, options) : true;\n\n if (hasPermCheck && hasRoleCheck) {\n return combine === 'or' ? permOk || roleOk : permOk && roleOk;\n }\n\n return hasPermCheck ? permOk : roleOk;\n}\n\ntype ElWithPermission = HTMLElement & {\n __angelPermissionDisplay?: string;\n __angelPermissionUnsubscribe?: () => void;\n};\n\nfunction applyVisibility(\n el: ElWithPermission,\n allowed: boolean,\n display?: string,\n): void {\n if (el.__angelPermissionDisplay === undefined) {\n el.__angelPermissionDisplay = el.style.display;\n }\n\n if (allowed) {\n el.style.display = display ?? el.__angelPermissionDisplay ?? '';\n el.removeAttribute('aria-hidden');\n } else {\n el.style.display = 'none';\n el.setAttribute('aria-hidden', 'true');\n }\n}\n\n/**\n * Create a `v-permission` directive bound to a specific store.\n * Prefer installing via `createPermissionPlugin()` which registers this automatically.\n */\nexport function createVPermission(\n store: PermissionStore,\n): Directive<ElWithPermission, PermissionDirectiveValue> {\n return {\n mounted(el, binding) {\n const update = () => {\n const { display } = parseBinding(binding);\n applyVisibility(el, isAllowed(store, binding), display);\n };\n\n update();\n el.__angelPermissionUnsubscribe = store.subscribe(update);\n },\n\n updated(el, binding) {\n const { display } = parseBinding(binding);\n applyVisibility(el, isAllowed(store, binding), display);\n },\n\n unmounted(el) {\n el.__angelPermissionUnsubscribe?.();\n delete el.__angelPermissionUnsubscribe;\n delete el.__angelPermissionDisplay;\n },\n };\n}\n","import { computed, defineComponent, type PropType } from 'vue';\nimport type { MatchMode, PermissionCode, RoleCode } from '../core';\nimport { usePermission } from './plugin';\n\n/**\n * Conditionally render slot content based on permission / role.\n *\n * @example\n * <Can permission=\"user:edit\">\n * <button>Edit</button>\n * </Can>\n *\n * <Can :permission=\"['user:edit', 'user:delete']\" mode=\"all\">\n * <AdminPanel />\n * <template #fallback>No access</template>\n * </Can>\n */\nexport const Can = defineComponent({\n name: 'Can',\n props: {\n permission: {\n type: [String, Array] as PropType<PermissionCode | PermissionCode[]>,\n default: undefined,\n },\n role: {\n type: [String, Array] as PropType<RoleCode | RoleCode[]>,\n default: undefined,\n },\n mode: {\n type: String as PropType<MatchMode>,\n default: 'any',\n },\n combine: {\n type: String as PropType<'and' | 'or'>,\n default: 'and',\n },\n },\n setup(props, { slots }) {\n const { hasPermission, hasRole, permissions, roles, isSuperAdmin } = usePermission();\n\n const allowed = computed(() => {\n void permissions.value;\n void roles.value;\n void isSuperAdmin.value;\n\n const hasPermCheck = props.permission !== undefined;\n const hasRoleCheck = props.role !== undefined;\n\n if (!hasPermCheck && !hasRoleCheck) return true;\n\n const options = { mode: props.mode };\n const permOk = hasPermCheck ? hasPermission(props.permission!, options) : true;\n const roleOk = hasRoleCheck ? hasRole(props.role!, options) : true;\n\n if (hasPermCheck && hasRoleCheck) {\n return props.combine === 'or' ? permOk || roleOk : permOk && roleOk;\n }\n\n return hasPermCheck ? permOk : roleOk;\n });\n\n return () => {\n if (allowed.value) {\n return slots.default?.();\n }\n return slots.fallback?.() ?? null;\n };\n },\n});\n"],"mappings":"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","names":["import_vue","import_core"]}
@@ -0,0 +1,173 @@
1
+ import * as vue from 'vue';
2
+ import { InjectionKey, ComputedRef, Plugin, Directive, PropType } from 'vue';
3
+
4
+ type PermissionCode = string;
5
+ type RoleCode = string;
6
+ interface PermissionState {
7
+ /** Permission codes owned by the current user */
8
+ permissions: PermissionCode[];
9
+ /** Roles owned by the current user */
10
+ roles: RoleCode[];
11
+ /** Super admin bypasses all checks when true */
12
+ isSuperAdmin?: boolean;
13
+ }
14
+ type MatchMode = 'all' | 'any';
15
+ interface CheckOptions {
16
+ /**
17
+ * `any` — pass when at least one code matches (default)
18
+ * `all` — pass only when every code matches
19
+ */
20
+ mode?: MatchMode;
21
+ }
22
+ type PermissionListener = (state: PermissionState) => void;
23
+ interface PermissionChecker {
24
+ hasPermission(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
25
+ hasRole(codes: RoleCode | RoleCode[], options?: CheckOptions): boolean;
26
+ can(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
27
+ getState(): PermissionState;
28
+ }
29
+
30
+ /**
31
+ * Mutable permission store shared by React / Vue adapters.
32
+ * Framework-agnostic — safe to use in Node, browser, or any UI lib.
33
+ */
34
+ declare class PermissionStore implements PermissionChecker {
35
+ private state;
36
+ private permissionSet;
37
+ private roleSet;
38
+ private listeners;
39
+ constructor(initial?: Partial<PermissionState>);
40
+ getState(): PermissionState;
41
+ setState(next: Partial<PermissionState>): void;
42
+ setPermissions(permissions: PermissionCode[]): void;
43
+ setRoles(roles: RoleCode[]): void;
44
+ setSuperAdmin(isSuperAdmin: boolean): void;
45
+ /** Replace permissions, roles and super-admin flag in one shot (typical after login). */
46
+ hydrate(payload: Partial<PermissionState>): void;
47
+ /** Clear all authz data (typical after logout). */
48
+ clear(): void;
49
+ hasPermission(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
50
+ hasRole(codes: RoleCode | RoleCode[], options?: CheckOptions): boolean;
51
+ /** Alias of `hasPermission` for template-friendly APIs. */
52
+ can(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
53
+ subscribe(listener: PermissionListener): () => void;
54
+ private emit;
55
+ }
56
+ declare function createPermissionStore(initial?: Partial<PermissionState>): PermissionStore;
57
+
58
+ declare const PERMISSION_STORE_KEY: InjectionKey<PermissionStore>;
59
+ interface PermissionPluginOptions {
60
+ /** Pass an existing store to share across apps. */
61
+ store?: PermissionStore;
62
+ /** Initial state when the plugin creates its own store. */
63
+ initialState?: Partial<PermissionState>;
64
+ /** Custom directive name. Default: `permission` → `v-permission`. */
65
+ directiveName?: string;
66
+ }
67
+ declare function createPermissionPlugin(options?: PermissionPluginOptions): Plugin & {
68
+ store: PermissionStore;
69
+ };
70
+ interface UsePermissionResult {
71
+ permissions: ComputedRef<PermissionCode[]>;
72
+ roles: ComputedRef<RoleCode[]>;
73
+ isSuperAdmin: ComputedRef<boolean>;
74
+ hasPermission: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;
75
+ hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;
76
+ can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;
77
+ setPermissions: (permissions: PermissionCode[]) => void;
78
+ setRoles: (roles: RoleCode[]) => void;
79
+ setSuperAdmin: (isSuperAdmin: boolean) => void;
80
+ hydrate: (payload: Partial<PermissionState>) => void;
81
+ clear: () => void;
82
+ store: PermissionStore;
83
+ }
84
+ /**
85
+ * Reactive permission API for Vue 3 Composition API.
86
+ */
87
+ declare function usePermission(store?: PermissionStore): UsePermissionResult;
88
+ declare function useHasPermission(codes: PermissionCode | PermissionCode[], options?: CheckOptions, store?: PermissionStore): ComputedRef<boolean>;
89
+ declare function useHasRole(codes: RoleCode | RoleCode[], options?: CheckOptions, store?: PermissionStore): ComputedRef<boolean>;
90
+ declare module 'vue' {
91
+ interface ComponentCustomProperties {
92
+ $permission: PermissionStore;
93
+ $can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;
94
+ $hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;
95
+ }
96
+ }
97
+
98
+ type PermissionDirectiveValue = PermissionCode | PermissionCode[] | {
99
+ permission?: PermissionCode | PermissionCode[];
100
+ role?: RoleCode | RoleCode[];
101
+ mode?: MatchMode;
102
+ /** When both permission and role are set. Default: `and`. */
103
+ combine?: 'and' | 'or';
104
+ /** CSS display value when allowed. Default: restores original display. */
105
+ display?: string;
106
+ };
107
+ type ElWithPermission = HTMLElement & {
108
+ __angelPermissionDisplay?: string;
109
+ __angelPermissionUnsubscribe?: () => void;
110
+ };
111
+ /**
112
+ * Create a `v-permission` directive bound to a specific store.
113
+ * Prefer installing via `createPermissionPlugin()` which registers this automatically.
114
+ */
115
+ declare function createVPermission(store: PermissionStore): Directive<ElWithPermission, PermissionDirectiveValue>;
116
+
117
+ /**
118
+ * Conditionally render slot content based on permission / role.
119
+ *
120
+ * @example
121
+ * <Can permission="user:edit">
122
+ * <button>Edit</button>
123
+ * </Can>
124
+ *
125
+ * <Can :permission="['user:edit', 'user:delete']" mode="all">
126
+ * <AdminPanel />
127
+ * <template #fallback>No access</template>
128
+ * </Can>
129
+ */
130
+ declare const Can: vue.DefineComponent<vue.ExtractPropTypes<{
131
+ permission: {
132
+ type: PropType<PermissionCode | PermissionCode[]>;
133
+ default: undefined;
134
+ };
135
+ role: {
136
+ type: PropType<RoleCode | RoleCode[]>;
137
+ default: undefined;
138
+ };
139
+ mode: {
140
+ type: PropType<MatchMode>;
141
+ default: string;
142
+ };
143
+ combine: {
144
+ type: PropType<"and" | "or">;
145
+ default: string;
146
+ };
147
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
148
+ [key: string]: any;
149
+ }>[] | null | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
150
+ permission: {
151
+ type: PropType<PermissionCode | PermissionCode[]>;
152
+ default: undefined;
153
+ };
154
+ role: {
155
+ type: PropType<RoleCode | RoleCode[]>;
156
+ default: undefined;
157
+ };
158
+ mode: {
159
+ type: PropType<MatchMode>;
160
+ default: string;
161
+ };
162
+ combine: {
163
+ type: PropType<"and" | "or">;
164
+ default: string;
165
+ };
166
+ }>> & Readonly<{}>, {
167
+ role: string | string[];
168
+ permission: string | string[];
169
+ mode: MatchMode;
170
+ combine: "and" | "or";
171
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
172
+
173
+ export { Can, type CheckOptions, type MatchMode, PERMISSION_STORE_KEY, type PermissionChecker, type PermissionCode, type PermissionDirectiveValue, type PermissionListener, type PermissionPluginOptions, type PermissionState, PermissionStore, type RoleCode, type UsePermissionResult, createPermissionPlugin, createPermissionStore, createVPermission, useHasPermission, useHasRole, usePermission };
@@ -0,0 +1,173 @@
1
+ import * as vue from 'vue';
2
+ import { InjectionKey, ComputedRef, Plugin, Directive, PropType } from 'vue';
3
+
4
+ type PermissionCode = string;
5
+ type RoleCode = string;
6
+ interface PermissionState {
7
+ /** Permission codes owned by the current user */
8
+ permissions: PermissionCode[];
9
+ /** Roles owned by the current user */
10
+ roles: RoleCode[];
11
+ /** Super admin bypasses all checks when true */
12
+ isSuperAdmin?: boolean;
13
+ }
14
+ type MatchMode = 'all' | 'any';
15
+ interface CheckOptions {
16
+ /**
17
+ * `any` — pass when at least one code matches (default)
18
+ * `all` — pass only when every code matches
19
+ */
20
+ mode?: MatchMode;
21
+ }
22
+ type PermissionListener = (state: PermissionState) => void;
23
+ interface PermissionChecker {
24
+ hasPermission(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
25
+ hasRole(codes: RoleCode | RoleCode[], options?: CheckOptions): boolean;
26
+ can(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
27
+ getState(): PermissionState;
28
+ }
29
+
30
+ /**
31
+ * Mutable permission store shared by React / Vue adapters.
32
+ * Framework-agnostic — safe to use in Node, browser, or any UI lib.
33
+ */
34
+ declare class PermissionStore implements PermissionChecker {
35
+ private state;
36
+ private permissionSet;
37
+ private roleSet;
38
+ private listeners;
39
+ constructor(initial?: Partial<PermissionState>);
40
+ getState(): PermissionState;
41
+ setState(next: Partial<PermissionState>): void;
42
+ setPermissions(permissions: PermissionCode[]): void;
43
+ setRoles(roles: RoleCode[]): void;
44
+ setSuperAdmin(isSuperAdmin: boolean): void;
45
+ /** Replace permissions, roles and super-admin flag in one shot (typical after login). */
46
+ hydrate(payload: Partial<PermissionState>): void;
47
+ /** Clear all authz data (typical after logout). */
48
+ clear(): void;
49
+ hasPermission(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
50
+ hasRole(codes: RoleCode | RoleCode[], options?: CheckOptions): boolean;
51
+ /** Alias of `hasPermission` for template-friendly APIs. */
52
+ can(codes: PermissionCode | PermissionCode[], options?: CheckOptions): boolean;
53
+ subscribe(listener: PermissionListener): () => void;
54
+ private emit;
55
+ }
56
+ declare function createPermissionStore(initial?: Partial<PermissionState>): PermissionStore;
57
+
58
+ declare const PERMISSION_STORE_KEY: InjectionKey<PermissionStore>;
59
+ interface PermissionPluginOptions {
60
+ /** Pass an existing store to share across apps. */
61
+ store?: PermissionStore;
62
+ /** Initial state when the plugin creates its own store. */
63
+ initialState?: Partial<PermissionState>;
64
+ /** Custom directive name. Default: `permission` → `v-permission`. */
65
+ directiveName?: string;
66
+ }
67
+ declare function createPermissionPlugin(options?: PermissionPluginOptions): Plugin & {
68
+ store: PermissionStore;
69
+ };
70
+ interface UsePermissionResult {
71
+ permissions: ComputedRef<PermissionCode[]>;
72
+ roles: ComputedRef<RoleCode[]>;
73
+ isSuperAdmin: ComputedRef<boolean>;
74
+ hasPermission: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;
75
+ hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;
76
+ can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;
77
+ setPermissions: (permissions: PermissionCode[]) => void;
78
+ setRoles: (roles: RoleCode[]) => void;
79
+ setSuperAdmin: (isSuperAdmin: boolean) => void;
80
+ hydrate: (payload: Partial<PermissionState>) => void;
81
+ clear: () => void;
82
+ store: PermissionStore;
83
+ }
84
+ /**
85
+ * Reactive permission API for Vue 3 Composition API.
86
+ */
87
+ declare function usePermission(store?: PermissionStore): UsePermissionResult;
88
+ declare function useHasPermission(codes: PermissionCode | PermissionCode[], options?: CheckOptions, store?: PermissionStore): ComputedRef<boolean>;
89
+ declare function useHasRole(codes: RoleCode | RoleCode[], options?: CheckOptions, store?: PermissionStore): ComputedRef<boolean>;
90
+ declare module 'vue' {
91
+ interface ComponentCustomProperties {
92
+ $permission: PermissionStore;
93
+ $can: (codes: PermissionCode | PermissionCode[], options?: CheckOptions) => boolean;
94
+ $hasRole: (codes: RoleCode | RoleCode[], options?: CheckOptions) => boolean;
95
+ }
96
+ }
97
+
98
+ type PermissionDirectiveValue = PermissionCode | PermissionCode[] | {
99
+ permission?: PermissionCode | PermissionCode[];
100
+ role?: RoleCode | RoleCode[];
101
+ mode?: MatchMode;
102
+ /** When both permission and role are set. Default: `and`. */
103
+ combine?: 'and' | 'or';
104
+ /** CSS display value when allowed. Default: restores original display. */
105
+ display?: string;
106
+ };
107
+ type ElWithPermission = HTMLElement & {
108
+ __angelPermissionDisplay?: string;
109
+ __angelPermissionUnsubscribe?: () => void;
110
+ };
111
+ /**
112
+ * Create a `v-permission` directive bound to a specific store.
113
+ * Prefer installing via `createPermissionPlugin()` which registers this automatically.
114
+ */
115
+ declare function createVPermission(store: PermissionStore): Directive<ElWithPermission, PermissionDirectiveValue>;
116
+
117
+ /**
118
+ * Conditionally render slot content based on permission / role.
119
+ *
120
+ * @example
121
+ * <Can permission="user:edit">
122
+ * <button>Edit</button>
123
+ * </Can>
124
+ *
125
+ * <Can :permission="['user:edit', 'user:delete']" mode="all">
126
+ * <AdminPanel />
127
+ * <template #fallback>No access</template>
128
+ * </Can>
129
+ */
130
+ declare const Can: vue.DefineComponent<vue.ExtractPropTypes<{
131
+ permission: {
132
+ type: PropType<PermissionCode | PermissionCode[]>;
133
+ default: undefined;
134
+ };
135
+ role: {
136
+ type: PropType<RoleCode | RoleCode[]>;
137
+ default: undefined;
138
+ };
139
+ mode: {
140
+ type: PropType<MatchMode>;
141
+ default: string;
142
+ };
143
+ combine: {
144
+ type: PropType<"and" | "or">;
145
+ default: string;
146
+ };
147
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
148
+ [key: string]: any;
149
+ }>[] | null | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
150
+ permission: {
151
+ type: PropType<PermissionCode | PermissionCode[]>;
152
+ default: undefined;
153
+ };
154
+ role: {
155
+ type: PropType<RoleCode | RoleCode[]>;
156
+ default: undefined;
157
+ };
158
+ mode: {
159
+ type: PropType<MatchMode>;
160
+ default: string;
161
+ };
162
+ combine: {
163
+ type: PropType<"and" | "or">;
164
+ default: string;
165
+ };
166
+ }>> & Readonly<{}>, {
167
+ role: string | string[];
168
+ permission: string | string[];
169
+ mode: MatchMode;
170
+ combine: "and" | "or";
171
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
172
+
173
+ export { Can, type CheckOptions, type MatchMode, PERMISSION_STORE_KEY, type PermissionChecker, type PermissionCode, type PermissionDirectiveValue, type PermissionListener, type PermissionPluginOptions, type PermissionState, PermissionStore, type RoleCode, type UsePermissionResult, createPermissionPlugin, createPermissionStore, createVPermission, useHasPermission, useHasRole, usePermission };