{"version":3,"file":"index.cjs","sources":["../src/Store.tsx","../src/components/Loader.tsx","../src/components/Protected.tsx","../src/utils/elementParser.tsx","../src/utils/getRoutes.ts","../src/utils/pathParser.ts","../src/components/Router.tsx"],"sourcesContent":["/**\n * Store using context api\n * @author Yousuf Kalim\n */\nimport React, { useContext, useState, createContext, ReactElement, ReactNode } from 'react';\n\n// Initializing Create Context Hook\ninterface AuthContextInterface {\n  auth: boolean | null;\n  setAuth: Function;\n}\nconst authContext = createContext<AuthContextInterface | null>(null);\n\ninterface ConfigContextInterface {\n  config: {\n    isAuthenticated?: Function;\n    showLoader: boolean;\n    loader: any;\n  };\n}\nconst configContext = createContext<ConfigContextInterface | null>(null);\n\n// We are also initializing useContexts here\n// we only call these functions where we need that data\nexport function Auth(): any {\n  return useContext(authContext);\n}\n\nexport function Config(): any {\n  return useContext(configContext);\n}\n\n/**\n * Store Provider with the config provided by the user\n * @param Function to check if the user is authenticated\n * @param showLoader Boolean to show the loader\n * @param loader Image to show as the loader\n * @param children Children of the component\n * @returns {ReactElement}\n * @constructor StoreProvider\n */\n// Initializing Store Provider\ninterface StoreProps {\n  children: ReactNode;\n  isAuthenticated?: Function;\n  showLoader?: boolean;\n  loader?: any;\n}\n// eslint-disable-next-line react/prop-types\nexport function StoreProvider({\n  isAuthenticated,\n  showLoader = true,\n  loader = 'https://i.imgur.com/FhvNntt.gif',\n  children,\n}: StoreProps): ReactElement {\n  // Initializing State\n  const [auth, setAuth] = useState(null);\n  const [config] = useState({\n    isAuthenticated,\n    showLoader,\n    loader,\n  });\n\n  // Render\n  return (\n    <authContext.Provider value={{ auth, setAuth }}>\n      <configContext.Provider value={{ config }}>{children}</configContext.Provider>\n    </authContext.Provider>\n  );\n}\n","/**\n * Loader component\n * @author Yousuf Kalim\n */\nimport React, { ReactElement } from 'react';\nimport { Config } from '../Store';\n\n/**\n * Loader\n * @returns {ReactElement}\n * @constructor Loader\n */\nfunction Loader(): ReactElement {\n  const { config } = Config(); // Get the config from the store\n\n  return (\n    <div\n      className=\"loader\"\n      style={{\n        height: '100vh',\n        width: '100%',\n        backgroundColor: 'white',\n        position: 'absolute',\n        zIndex: 1000,\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n      }}\n    >\n      {/* If user has provided the custom loader then show, otherwise show default */}\n      <img src={config.loader} alt=\"loader\" />\n    </div>\n  );\n}\nexport default Loader;\n","/**\n * Protected component to check if the user is authenticated or not and then render the component\n * @author Yousuf Kalim\n */\nimport React, { useEffect, ReactNode, ReactElement } from 'react';\nimport { Navigate } from 'react-router-dom';\nimport { Auth, Config } from '../Store';\nimport Loader from './Loader';\n\n/**\n * Protected\n * @param failureRedirect {string} - The path to redirect if the user is not authenticated\n * @param roles\n * @param children {ReactNode} - The component to render if the user is authenticated\n * @returns {ReactElement}\n */\nfunction Protected({\n  failureRedirect = '/',\n  roles,\n  children,\n}: {\n  failureRedirect?: string;\n  roles?: string[];\n  children: ReactNode;\n}): ReactElement {\n  const { auth, setAuth } = Auth(); // Get the auth state from the store\n  const {\n    config: { isAuthenticated, showLoader },\n  } = Config(); // Get the config from the store\n\n  useEffect(() => {\n    // Check if the user is authenticated or not\n    if (isAuthenticated) {\n      isAuthenticated()\n        .then((res: any) => {\n          if (res) {\n            if (roles?.length && roles.includes(res.role)) {\n              // If the user is authenticated then set the auth state to true\n              return setAuth(true);\n            } else if (!roles?.length) {\n              // If the user is authenticated then set the auth state to true\n              setAuth(true);\n            } else {\n              setAuth(false);\n            }\n          } else {\n            setAuth(false);\n          }\n        })\n        .catch(() => setAuth(false)); // If the user is not authenticated then set the auth state to false\n    } else {\n      setAuth(false);\n    }\n  }, [isAuthenticated, setAuth]);\n\n  // eslint-disable-next-line no-nested-ternary\n  return auth === null ? ( // If the auth state is null then show the loader\n    showLoader && <Loader />\n  ) : auth ? ( // If the auth state is true then render the children\n    children\n  ) : (\n    // If the auth state is false then redirect to the failureRedirect path\n    <Navigate to={failureRedirect} />\n  );\n}\n\nexport default Protected;\n","/**\n * Parse the routes according to the config provided\n * @author Yousuf Kalim\n */\nimport React, { ReactElement } from 'react';\nimport { Route, Navigate } from 'react-router-dom';\nimport Protected from '../components/Protected';\nimport { RouteProps } from '../types/types';\n\n/**\n * elementParser\n * @param route {Object} - Route object\n * @returns {ReactElement} - Route element\n */\nexport default function elementParser(route: RouteProps): ReactElement {\n  // Navigated route\n  if (route.navigate) {\n    return <Route key={route.path} path={route.path} element={<Navigate to={route.navigate} />} />;\n  }\n\n  // Protected route\n  if (route.protected) {\n    // This will call the protected component and pass the route as props\n    return (\n      <Route\n        key={route.path}\n        path={route.path}\n        element={\n          <Protected failureRedirect={route.failureRedirect} roles={route.roles}>\n            {route.element}\n          </Protected>\n        }\n      />\n    );\n  }\n\n  // Simple route\n  return <Route key={route.path} path={route.path} element={route.element} />;\n}\n","/**\n * Parse the routes from the config file\n * @author Yousuf Kalim\n */\nimport { ReactElement } from 'react';\nimport pathParser from './pathParser';\nimport elementParser from './elementParser';\nimport { RouteProps } from '../types/types';\n\n/**\n * getRoutes\n * @param routes {Array} - Array of routes\n * @param parentPath {String} - Parent path\n * @returns {*} - Array of rendered routes\n */\nexport default function getRoutes(routes: RouteProps[], parentPath = ''): ReactElement[] {\n  // Loop through the routes and create the route elements\n  const renderedRoutes = routes.map((route) => {\n    // eslint-disable-next-line no-param-reassign\n    route.path = pathParser(parentPath, route.path); // This will create the path by appending parent path if exist\n\n    let children: ReactElement[] = [];\n    if (route.children) {\n      // Recursively call the function to get the children routes\n      children = getRoutes(route.children, route.path);\n    }\n\n    // Create the route element using the element parser\n    return [...children, elementParser(route)];\n  });\n\n  // Return the flatten array of routes and children\n  return renderedRoutes.flat();\n}\n","/**\n * Appending the child path to the parent path\n * @author Yousuf Kalim\n */\n\n/**\n * pathParser\n * @param parent {String} - Parent path\n * @param child {String} - Child path\n * @returns {string|string} - Path\n */\nexport default function pathParser(parent: string, child: string): string {\n  const parentPath = parent.split('/');\n  const childPath = child.split('/');\n\n  // removing the duplicates\n  const path = [...new Set([...parentPath, ...childPath])].join('/');\n\n  // Add the slash at the start of the path\n  return path[0] === '/' ? path : `/${path}`;\n}\n","/**\n * Main router component that handles the routing of the application\n * @author Yousuf Kalim\n */\nimport React, { ReactElement } from 'react';\nimport { Routes } from 'react-router-dom';\nimport { StoreProvider } from '../Store';\nimport getRoutes from '../utils/getRoutes';\nimport { RouteProps } from '../types/types';\n\n/**\n * Router\n * @param props Props passed to the component\n * @returns {ReactElement}\n * @constructor Router\n */\nexport interface UserProps {\n  routes: RouteProps[];\n  isAuthenticated?: Function;\n  showLoader?: boolean;\n  loader?: any;\n}\nexport default function Router(props: UserProps): ReactElement {\n  return (\n    <StoreProvider {...props}>\n      <Routes>{getRoutes(props.routes)}</Routes>\n    </StoreProvider>\n  );\n}\n"],"names":["authContext","createContext","configContext","Config","useContext","StoreProvider","isAuthenticated","showLoader","_ref$showLoader","_ref$loader","_ref","loader","children","useState","auth","setAuth","_useState","_useState2","React","createElement","Provider","value","config","Loader","className","style","height","width","backgroundColor","position","zIndex","display","justifyContent","alignItems","src","alt","Protected","failureRedirect","_ref$failureRedirect","roles","_Auth","_Config$config","useEffect","then","res","length","includes","role","Navigate","to","elementParser","route","Route","navigate","key","path","element","routes","parentPath","map","parent","child","split","childPath","concat","Set","join","pathParser","getRoutes","renderedRoutes","flat","props","Routes"],"mappings":"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"}