@casl/vue
Version:
Vue plugin for CASL which makes it easy to add permissions in any Vue application
1 lines • 6.42 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["Ability"],"sources":["../../src/reactiveAbility.ts","../../src/useAbility.ts","../../src/component/can.ts","../../src/plugin.ts"],"sourcesContent":["import { AnyAbility, SubjectType } from '@casl/ability';\nimport { ref } from 'vue';\n\nconst hasOwn: (o: object, v: PropertyKey) => boolean = Object.hasOwn ||\n ((obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop));\n\nexport function reactiveAbility(ability: AnyAbility) {\n if (hasOwn(ability, 'possibleRulesFor')) return ability;\n\n const watcher = ref(true);\n ability.on('updated', () => {\n watcher.value = !watcher.value;\n });\n\n const possibleRulesFor = ability.possibleRulesFor.bind(ability);\n ability.possibleRulesFor = (action: string, subject: SubjectType) => {\n watcher.value = watcher.value; // eslint-disable-line\n return possibleRulesFor(action, subject);\n };\n ability.can = ability.can.bind(ability);\n ability.cannot = ability.cannot.bind(ability);\n\n return ability;\n}\n","import type { AnyAbility, MongoAbility } from '@casl/ability';\nimport { inject, InjectionKey, provide } from 'vue';\nimport { reactiveAbility } from './reactiveAbility';\n\nexport const ABILITY_TOKEN: InjectionKey<AnyAbility> = Symbol('ability');\n\nexport function useAbility<T extends AnyAbility = MongoAbility>(): T {\n const ability = inject<T>(ABILITY_TOKEN);\n\n if (!ability) {\n throw new Error(\n 'Cannot inject Ability instance because it was not provided. ' +\n 'Did you forget to install abilitiesPlugin or call provideAbility in a parent component?'\n );\n }\n\n return ability;\n}\n\nexport function provideAbility(ability: AnyAbility) {\n provide(ABILITY_TOKEN, reactiveAbility(ability));\n}\n","import {\n Abilities,\n AbilityTuple,\n AnyAbility,\n Generics,\n IfString,\n MongoAbility,\n SubjectType\n} from '@casl/ability';\nimport { ComponentCustomProperties, defineComponent } from 'vue';\nimport { useAbility } from '../useAbility';\n\nexport type CanProps<T extends AnyAbility> = AbilityCanProps<Generics<T>['abilities']> & {\n not?: boolean,\n passThrough?: boolean\n};\n\nexport const Can = defineComponent<CanProps<VueAbility>>({\n name: 'Can',\n props: {\n I: String,\n do: String,\n a: [String, Function],\n an: [String, Function],\n this: [String, Function, Object],\n on: [String, Function, Object],\n not: Boolean,\n passThrough: Boolean,\n field: String\n } as any,\n setup(props, { slots }) {\n const $props = props as Record<string, any>;\n let actionProp = 'do';\n let subjectProp = 'on';\n\n if ($props[actionProp] === undefined) {\n actionProp = 'I';\n subjectProp = detectSubjectProp(props);\n }\n\n if (!$props[actionProp]) {\n throw new Error('Neither `I` nor `do` prop was passed in <Can>');\n }\n\n if (!slots.default) {\n throw new Error('Expects to receive default slot');\n }\n\n const ability = useAbility<VueAbility>();\n\n return () => {\n const rule = ability.relevantRuleFor($props[actionProp], $props[subjectProp], $props.field);\n let isAllowed = !!rule && !rule.inverted;\n if (props.not) isAllowed = !isAllowed;\n\n if (!props.passThrough && !isAllowed) {\n return null;\n }\n\n return slots.default!({\n allowed: isAllowed,\n reason: rule?.reason,\n ability,\n });\n };\n }\n});\n\ntype AbilityCanProps<\n T extends Abilities,\n Else = IfString<T, { do: T } | { I: T }>\n> = T extends AbilityTuple\n ? { do: T[0], on: T[1], field?: string } |\n { I: T[0], a: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], an: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], this: Exclude<T[1], SubjectType>, field?: string }\n : Else;\n\ntype VueAbility = ComponentCustomProperties extends { $ability: AnyAbility }\n ? ComponentCustomProperties['$ability']\n : MongoAbility;\n\nfunction detectSubjectProp(props: Record<string, unknown>) {\n if (props.a !== undefined) {\n return 'a';\n }\n\n if (props.this !== undefined) {\n return 'this';\n }\n\n if (props.an !== undefined) {\n return 'an';\n }\n\n return '';\n}\n","import { App } from 'vue';\nimport { AnyAbility, Ability, MongoAbility } from '@casl/ability';\nimport { ABILITY_TOKEN } from './useAbility';\nimport { reactiveAbility } from './reactiveAbility';\n\nexport interface AbilityPluginOptions {\n useGlobalProperties?: boolean\n}\n\nexport function abilitiesPlugin(app: App, ability: AnyAbility, options?: AbilityPluginOptions) {\n if (!ability || !(ability instanceof Ability)) {\n throw new Error('Please, provide an Ability instance to abilitiesPlugin plugin');\n }\n\n app.provide(ABILITY_TOKEN, reactiveAbility(ability));\n\n if (options && options.useGlobalProperties) {\n app.config.globalProperties.$ability = ability as MongoAbility;\n app.config.globalProperties.$can = ability.can.bind(ability);\n }\n}\n"],"mappings":";;;;;;AAGA,MAAM,IAAiD,OAAO,UAAA,EAC1D,GAAK,MAAS,OAAO,UAAU,eAAe,KAAK,GAAK;;AAE5D,SAAgB,EAAgB;IAC9B,IAAI,EAAO,GAAS,qBAAqB,OAAO;IAEhD,MAAM,KAAA,GAAA,EAAA,MAAc;IACpB,EAAQ,GAAG,WAAA;QACT,EAAQ,SAAS,EAAQ;;IAG3B,MAAM,IAAmB,EAAQ,iBAAiB,KAAK;IAQvD,OAPA,EAAQ,mBAAA,CAAoB,GAAgB,OAC1C,EAAQ,QAAQ,EAAQ,OACjB,EAAiB,GAAQ,KAElC,EAAQ,MAAM,EAAQ,IAAI,KAAK;IAC/B,EAAQ,SAAS,EAAQ,OAAO,KAAK,IAE9B;;;AClBT,MAAa,IAA0C,OAAO;;AAE9D,SAAgB;IACd,MAAM,KAAA,GAAA,EAAA,QAAoB;IAE1B,KAAK,GACH,MAAM,IAAI,MACR;IAKJ,OAAO;;;ACCT,MAAa,KAAA,GAAA,EAAA,iBAA4C;IACvD,MAAM;IACN,OAAO;QACL,GAAG;QACH,IAAI;QACJ,GAAG,EAAC,QAAQ;QACZ,IAAI,EAAC,QAAQ;QACb,MAAM,EAAC,QAAQ,UAAU;QACzB,IAAI,EAAC,QAAQ,UAAU;QACvB,KAAK;QACL,aAAa;QACb,OAAO;;IAET,KAAA,CAAM,IAAO,OAAE;QACb,MAAM,IAAS;QACf,IAAI,IAAa,MACb,IAAc;QAOlB,SAL2B,MAAvB,EAAO,OACT,IAAa,KACb,IA6CN,SAA2B;YACzB,SAAgB,MAAZ,EAAM,GACR,OAAO;YAGT,SAAmB,MAAf,EAAM,MACR,OAAO;YAGT,SAAiB,MAAb,EAAM,IACR,OAAO;YAGT,OAAO;SA1DW,CAAkB,MAG7B,EAAO,IACV,MAAM,IAAI,MAAM;QAGlB,KAAK,EAAM,SACT,MAAM,IAAI,MAAM;QAGlB,MAAM,IAAU;QAEhB,OAAA;YACE,MAAM,IAAO,EAAQ,gBAAgB,EAAO,IAAa,EAAO,IAAc,EAAO;YACrF,IAAI,MAAc,MAAS,EAAK;YAGhC,OAFI,EAAM,QAAK,KAAa,IAEvB,EAAM,eAAgB,IAIpB,EAAM,QAAS;gBACpB,SAAS;gBACT,QAAQ,GAAM;gBACd;iBANO;;;;;sEC/Cf,SAAgC,GAAU,GAAqB;IAC7D,MAAK,KAAa,aAAmBA,EAAAA,UACnC,MAAM,IAAI,MAAM;IAGlB,EAAI,QAAQ,GAAe,EAAgB,KAEvC,KAAW,EAAQ,wBACrB,EAAI,OAAO,iBAAiB,WAAW;IACvC,EAAI,OAAO,iBAAiB,OAAO,EAAQ,IAAI,KAAK;4BFCxD,SAA+B;KAC7B,GAAA,EAAA,SAAQ,GAAe,EAAgB"}