{"version":3,"sources":["../../src/index.ts","../../src/context/AbilityContext.ts","../../src/context/AbilityProvider.tsx","../../src/hooks/useStorage.ts","../../src/hooks/useAbility.ts","../../src/components/Can.tsx","../../src/components/Cannot.tsx"],"sourcesContent":["import AbilityContext from './context/AbilityContext';\nimport { AbilityProvider } from './context/AbilityProvider';\nimport { Can } from './components/Can';\nimport { Cannot } from './components/Cannot';\nimport useAbility from './hooks/useAbility';\n\nexport { AbilityContext, AbilityProvider, useAbility, Can, Cannot };\n","import { createContext } from 'react';\nimport { UseAbility } from '../types/Ability';\n\nconst AbilityContext = createContext<UseAbility>({} as UseAbility);\n\nexport default AbilityContext;\n","'use client';\nimport * as React from 'react';\nimport { useCallback, useEffect, useState, useRef } from 'react';\nimport { AbilityProviderProps, UseAbility } from '../types/Ability';\nimport AbilityContext from './AbilityContext';\nimport useStorage from '../hooks/useStorage';\n\nconst MICYO_STORAGE_KEY = 'micyo_abilities';\n\nexport const AbilityProvider = ({ list, persistent = true, children }: AbilityProviderProps) => {\n  const { setItem, getItem } = useStorage();\n  const [abilities, setAbilities] = useState<string[]>([]);\n  const isFirstRender = useRef(true);\n\n  // add new ability\n  const addAbility = useCallback(\n    (ability: string) => {\n      setAbilities((currentAbilities) =>\n        currentAbilities.indexOf(ability) === -1\n          ? [...currentAbilities, ability]\n          : [...currentAbilities]\n      );\n    },\n    [setAbilities]\n  );\n\n  // add new abilities\n  const addAbilities = useCallback(\n    (abilities: string[]) => {\n      setAbilities((currentAbilities) => {\n        const newAbilities = [...currentAbilities];\n\n        abilities.forEach((ability) => {\n          if (newAbilities.indexOf(ability) === -1) {\n            newAbilities.push(ability);\n          }\n        });\n\n        return [...newAbilities];\n      });\n    },\n    [setAbilities]\n  );\n\n  // remove ability\n  const removeAbility = useCallback(\n    (ability: string) => {\n      setAbilities((currentAbilities) => [\n        ...currentAbilities.filter((currentAbility) => currentAbility !== ability)\n      ]);\n    },\n    [setAbilities]\n  );\n\n  // remove abilities\n  const removeAbilities = useCallback(\n    (abilities: string[]) => {\n      setAbilities((currentAbilities) => [\n        ...currentAbilities.filter((ability) => abilities.indexOf(ability) === -1)\n      ]);\n    },\n    [setAbilities]\n  );\n\n  // clear abilities\n  const clearAbilities = useCallback(() => {\n    setAbilities([]);\n  }, [setAbilities]);\n\n  /** Check has ability */\n  const can = useCallback((ability: string) => abilities.indexOf(ability) >= 0, [abilities]);\n\n  // get latest changes from localStorage\n  useEffect(() => {\n    const abilityList = getItem(MICYO_STORAGE_KEY);\n\n    if (abilityList !== null && abilityList !== '' && isFirstRender.current && persistent) {\n      setAbilities(JSON.parse(abilityList || ''));\n    } else if (isFirstRender.current || !persistent) {\n      setAbilities(list || []);\n    }\n  }, [setAbilities, getItem, list, persistent]);\n\n  const updateAbilities = useCallback(\n    ({ key, newValue, oldValue }: StorageEvent) => {\n      if (key === MICYO_STORAGE_KEY && newValue !== null) {\n        setAbilities(JSON.parse(newValue));\n      } else if (key === MICYO_STORAGE_KEY && newValue === null) {\n        setAbilities(JSON.parse(oldValue || ''));\n      }\n    },\n    [setAbilities]\n  );\n\n  // listen localStorage changes\n  useEffect(() => {\n    window.addEventListener('storage', updateAbilities);\n\n    return () => window.removeEventListener('storage', updateAbilities);\n  }, []);\n\n  // push abilities update to across tabs\n  useEffect(() => {\n    if (!isFirstRender.current && persistent) {\n      setItem(MICYO_STORAGE_KEY, JSON.stringify(abilities));\n    } else {\n      isFirstRender.current = false;\n    }\n  }, [abilities, setItem, persistent]);\n\n  const contextValues: UseAbility = {\n    abilities,\n    setAbilities,\n    addAbility,\n    addAbilities,\n    removeAbility,\n    removeAbilities,\n    clearAbilities,\n    can\n  };\n\n  return <AbilityContext.Provider value={contextValues}>{children}</AbilityContext.Provider>;\n};\n","import { useCallback } from 'react';\nimport { UseStorage } from '../types/Storage';\n\nconst useStorage = (): UseStorage => {\n  const setItem = useCallback((key: string, item: any) => {\n    try {\n      window.localStorage.setItem(key, item);\n    } catch (error) {\n      console.warn(`Error setting localStorage key “${key}”:`, error);\n    }\n  }, []);\n\n  const getItem = useCallback((key: string) => {\n    try {\n      return window.localStorage.getItem(key);\n    } catch (error) {\n      console.warn(`Error getting localStorage key “${key}”:`, error);\n    }\n  }, []);\n\n  const removeItem = useCallback((key: string) => {\n    try {\n      window.localStorage.removeItem(key);\n    } catch (error) {\n      console.warn(`Error deleting localStorage key “${key}”:`, error);\n    }\n  }, []);\n\n  return { setItem, getItem, removeItem };\n};\n\nexport default useStorage;\n","import { useContext } from 'react';\nimport AbilityContext from '../context/AbilityContext';\nimport { UseAbility } from '../types/Ability';\n\n/**\n * Abilities Service - Get, modify, clear or remove abilities\n * @returns UseAbility - Abilities context\n */\nconst useAbility = (): UseAbility => useContext(AbilityContext);\n\nexport default useAbility;\n","import useAbility from '../hooks/useAbility';\nimport { CanProps } from '../types/Ability';\n\n/**\n * Check ability and render content\n * @param params {CanProps} - Ability checker\n * @param params.i {string} - Ability name\n * @param params.children {ReactElement} - Content\n * @returns {ReactNode} Content\n */\nexport const Can = ({ i, children }: CanProps) => {\n  const { can } = useAbility();\n  return can(i) && children;\n};\n","import useAbility from '../hooks/useAbility';\nimport { CanProps } from '../types/Ability';\n\n/**\n * Check ability and cannot render content\n * @param params {CanProps} - Ability checker\n * @param params.i {string} - Ability name\n * @param params.children {ReactElement} - Content\n * @returns {ReactNode} Content\n */\nexport const Cannot = ({ i, children }: CanProps) => {\n  const { can } = useAbility();\n  return !can(i) && children;\n};\n"],"mappings":"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","names":["src_exports","__export","AbilityContext_default","AbilityProvider","Can","Cannot","useAbility_default","__toCommonJS","import_react","AbilityContext","AbilityContext_default","React","import_react","import_react","useStorage","setItem","key","item","error","getItem","removeItem","useStorage_default","MICYO_STORAGE_KEY","AbilityProvider","list","persistent","children","setItem","getItem","useStorage_default","abilities","setAbilities","isFirstRender","addAbility","ability","currentAbilities","addAbilities","newAbilities","removeAbility","currentAbility","removeAbilities","clearAbilities","can","abilityList","updateAbilities","key","newValue","oldValue","contextValues","AbilityContext_default","import_react","useAbility","AbilityContext_default","useAbility_default","Can","i","children","can","useAbility_default","Cannot","i","children","can","useAbility_default"]}