{"_id":"@appbuckets/app-router","_rev":"38-448638036d0e740ef877a5ce169d6cd1","time":{"0.2.0":"2020-05-23T13:57:44.067Z","created":"2020-05-23T13:59:12.708Z","0.2.1":"2020-05-23T13:59:13.049Z","modified":"2022-04-04T14:44:40.615Z","0.2.0-beta.0":"2020-05-25T14:13:03.212Z","0.3.0-beta.0":"2020-05-25T14:15:15.430Z","0.3.0-beta.1":"2020-05-28T15:00:04.169Z","0.3.0-beta.2":"2020-06-15T14:23:29.304Z","0.3.0-beta.3":"2020-07-01T14:48:20.622Z","0.3.1":"2020-07-01T15:11:43.901Z","0.3.1-beta.1":"2020-07-01T16:59:57.366Z","0.3.1-beta.2":"2020-07-01T17:25:32.891Z","0.3.1-beta.3":"2020-07-02T09:55:16.850Z","0.3.2":"2020-07-22T08:36:39.260Z","0.3.21":"2020-11-18T18:56:59.862Z","1.0.0":"2020-12-07T17:30:52.146Z","1.0.1":"2020-12-07T18:02:48.386Z","1.0.2":"2020-12-07T18:06:18.088Z","1.0.3":"2020-12-07T18:18:46.633Z","1.0.4":"2020-12-07T22:51:14.905Z","1.0.5":"2020-12-07T23:08:57.958Z","1.0.6":"2020-12-08T21:39:59.142Z","1.0.7":"2020-12-08T22:13:14.223Z","1.0.8":"2020-12-11T18:10:02.131Z","1.0.9":"2020-12-22T17:18:58.931Z","1.1.0":"2021-02-23T11:31:37.298Z","1.1.1":"2021-03-02T13:48:28.867Z","1.1.11":"2021-03-02T14:02:10.946Z","1.1.12":"2021-03-24T10:24:01.173Z","1.1.13":"2021-04-07T09:57:17.519Z","1.1.14":"2021-04-07T23:41:33.477Z","1.1.15":"2021-11-28T19:20:35.253Z"},"name":"@appbuckets/app-router","dist-tags":{"latest":"1.1.15","next":"0.3.1-beta.3"},"versions":{"0.2.1":{"name":"@appbuckets/app-router","version":"0.2.1","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c ./rollup/rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" NODE_ENV=development WEBPACK_LIVE_SERVER=1 webpack-dev-server --progress","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'","prepare-development":"yarn install && yarn add -P react react-dom @types/react @types/react-dom"},"peerDependencies":{"@types/react":"~16.9.35","@types/react-dom":"~16.9.8","react":"~16.13.1","react-dom":"~16.13.1","react-router-dom":"~5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/circular-dependency-plugin":"^5.0.0","@types/mini-css-extract-plugin":"^0.9.1","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@types/webpack":"^4.41.13","@types/webpack-dev-server":"^3.10.1","@types/webpack-env":"^1.15.2","@types/webpack-merge":"^4.1.5","autoprefixer":"^9.8.0","circular-dependency-plugin":"^5.2.0","cross-env":"^7.0.2","css-declaration-sorter":"^5.1.2","css-loader":"^3.5.3","css-mqpacker":"^7.0.0","cssnano":"^4.1.10","html-loader":"^1.1.0","html-webpack-plugin":"^4.3.0","mini-css-extract-plugin":"^0.9.0","node-sass":"^4.14.1","postcss-discard-comments":"^4.0.2","postcss-discard-duplicates":"^4.0.2","postcss-import":"^12.0.1","postcss-import-url":"^5.1.0","postcss-loader":"^3.0.0","postcss-single-line":"^1.0.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-postcss":"^3.1.1","rollup-plugin-typescript2":"^0.27.1","sass-loader":"^8.0.2","source-map-loader":"^0.2.4","style-loader":"^1.2.1","ts-loader":"^7.0.4","ts-node":"^8.10.1","tsconfig-paths":"^3.9.0","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2","webpack":"^4.43.0","webpack-cli":"^3.3.11","webpack-dev-server":"^3.11.0"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"gitHead":"7819ed7abe66a5ba05c32debc3c3b723aaad9224","_id":"@appbuckets/app-router@0.2.1","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-YxAK83z9WH8hfulOCZuF01FZqRJRdM5CnFNRa3PhMKdiqxMMouSHuIifoLHssT/1PIiuXjGFdHz0MdvgmJCdZQ==","shasum":"6f5b01ae7cce2c2580a8081a9c629617e8e69142","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.2.1.tgz","fileCount":44,"unpackedSize":278334,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeySwxCRA9TVsSAnZWagAAmNUP/2k3dymemfrtbRfNxkVH\nBViNUO1UvIiPgsfLaoOTJd1vcRi5Gcvd2xfFdzWwH6M5JbJw2a7UJuwuWxqo\nQP90lJxxYrKSmHBwSwgoF1yppRgQkGhfG/eQ8zhOQ1sdvZbBoJPLENyNlcDf\nFAsf8n2lSBhuowwX872trKXckQ3J3qCGESrnmq44HVCyX9VfjchYmFB6gyoA\nnhc4Sn5dVhe7gNT8cyfswVB7RZq6co22UY+O+5fn4ERcWUAELoMK7XxmRRI0\nLNhRqU0hhxst5Pjka+2rQ3VBVKzuUvCllO2qwumF8ehAyTZ3/Hj4bspBvBCb\n317dCm6WjoF4kB1wOaVHS3J3k01jvTKwYv9TiAEFDPGzJBuo/rHLzd5dla9t\nnFgAqD58/kuZP+uvnKBQ+2MEb+LHYmjxyJDAuANgDWQaTlLLOaCtRkgVUkR4\nL7/EzyYLDoSF+bCQ56Zi2XzvcWDoLRpR5Z+1qz74mUBMR9VfaV5m2Mvk+q1V\nHQMlj9nE33Qe8hyifHqti/dSvq8WrPsKZWw7CLAwVYBZbcq2JLQOleTJaRWU\nS1ZYjlOTWoD2ZmSlIUIK3gd2aS/ic/gLbzbBQORckQ/EFpdy9xeo8tmu3gTT\ndzh4iET9R/tyeHAnqZLgIQ03YW942tUUobZbrPi0MBJ1fubcWgiuLnsSgKvH\nS/EM\r\n=0i46\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDE+7T59kjowRq0eBLJvcvDf8OCAhK1VtFJgHRuoJmLXAiEAoaiOMJM/NiuBdhT5AEmq1sx9W9jQgGh3B+qZ5etrLqI="}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.2.1_1590242352914_0.909403930739755"},"_hasShrinkwrap":false},"0.3.0-beta.0":{"name":"@appbuckets/app-router","version":"0.3.0-beta.0","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c ./rollup/rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" NODE_ENV=development WEBPACK_LIVE_SERVER=1 webpack-dev-server --progress","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'","prepare-development":"yarn install && yarn add -P react react-dom @types/react @types/react-dom"},"peerDependencies":{"@types/react":"~16.9.35","@types/react-dom":"~16.9.8","react":"~16.13.1","react-dom":"~16.13.1","react-router-dom":"~5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/circular-dependency-plugin":"^5.0.0","@types/mini-css-extract-plugin":"^0.9.1","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@types/webpack":"^4.41.13","@types/webpack-dev-server":"^3.10.1","@types/webpack-env":"^1.15.2","@types/webpack-merge":"^4.1.5","autoprefixer":"^9.8.0","circular-dependency-plugin":"^5.2.0","cross-env":"^7.0.2","css-declaration-sorter":"^5.1.2","css-loader":"^3.5.3","css-mqpacker":"^7.0.0","cssnano":"^4.1.10","html-loader":"^1.1.0","html-webpack-plugin":"^4.3.0","mini-css-extract-plugin":"^0.9.0","node-sass":"^4.14.1","postcss-discard-comments":"^4.0.2","postcss-discard-duplicates":"^4.0.2","postcss-import":"^12.0.1","postcss-import-url":"^5.1.0","postcss-loader":"^3.0.0","postcss-single-line":"^1.0.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-postcss":"^3.1.1","rollup-plugin-typescript2":"^0.27.1","sass-loader":"^8.0.2","source-map-loader":"^0.2.4","style-loader":"^1.2.1","ts-loader":"^7.0.4","ts-node":"^8.10.1","tsconfig-paths":"^3.9.0","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2","webpack":"^4.43.0","webpack-cli":"^3.3.11","webpack-dev-server":"^3.11.0"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","gitHead":"838d8ac8efc059b8d669a5f6482203ce96db1f22","_id":"@appbuckets/app-router@0.3.0-beta.0","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-h2g8MpUe/07BlozLroCdHNaoQrrRZK9FvxJ4reIzSmci00oNubIZNrTbQ6NkujMerzgeLw+B/pNiekIPsw0eKQ==","shasum":"759763bc6fba4703dbca2a79531cd9c1d89f0d94","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.0-beta.0.tgz","fileCount":47,"unpackedSize":290716,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJey9LzCRA9TVsSAnZWagAA7XgP+wQmqOtOkSi6PpvmzFUS\nCFtaKpQ+3zpyIc9pFysaOtiQWbgo86aMn7ff+ij8K/cUT1Wut7pNOlDRnkNS\nlULVJHrwQfYmgCjX+bPtd9sw0Zoe4CHTggro/WLqF2+Lj2UY+RWjexyhUmx6\nciCmrX/PvKMone8dldGJhbrMEgTU+yy1qnwtpz7o2ce/msKuma0cvQQwa/WR\nOpwhzNMeP0gFrU9oYobDXqV9VeQ5CV7qV6uLI9usob6Yc72AmskqfDIHv7r5\nDhTI0dWDF8JbCgNrDdOd4mCHBCBQMjlQoUalgmdBhxLBoyqDqpJaKgqAqDQ3\nWxpL+wvJUmJboV0McHM3kHOGge30t/vPtCJq4jsRHZCXSdppT4KMXzF+XRbB\npzvciGcAjyF6oOvzE3pcckLHykyUNBVDNJWEsJ+SRd1VJTcDRc49Z2V2Eezo\nbBVSTe/XtRddbuInuLb3A3Nozqs7Lv1pwzCJ5LVAESZCMNwxhI0nhcPm1dJ0\nU2K9in3akstRHN28WXSDAPgrhadB8xRhldocZfyGkCB7BHjauGXyPfVUYSgA\nGhid/xtH4O7ZVeB382ukwfv/8KC6bCRjWBzoQV4PwA9aEK/ZJ2fJPBHEoQa8\nb5QWIAX2yPnLFxxhQ0Y7UIUdsrFMnD1ylwe4sdpwiljhP1mzvpEKfNU3IV+4\nij3b\r\n=2/ib\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD0muuzDKEf8EpQh6TD8tACD85U25aAI/PtUFHbxuUyrwIhAP28KPXYk/6zxubRfPofyugy/ys67EbAxHWg4WFo4pvM"}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.0-beta.0_1590416115284_0.4352309623374342"},"_hasShrinkwrap":false},"0.3.0-beta.1":{"name":"@appbuckets/app-router","version":"0.3.0-beta.1","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c ./rollup/rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" NODE_ENV=development WEBPACK_LIVE_SERVER=1 webpack-dev-server --progress","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'","prepare-development":"yarn install && yarn add -P react react-dom @types/react @types/react-dom"},"peerDependencies":{"@types/react":"~16.9.35","@types/react-dom":"~16.9.8","react":"~16.13.1","react-dom":"~16.13.1","react-router-dom":"~5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/circular-dependency-plugin":"^5.0.0","@types/mini-css-extract-plugin":"^0.9.1","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@types/webpack":"^4.41.13","@types/webpack-dev-server":"^3.10.1","@types/webpack-env":"^1.15.2","@types/webpack-merge":"^4.1.5","autoprefixer":"^9.8.0","circular-dependency-plugin":"^5.2.0","cross-env":"^7.0.2","css-declaration-sorter":"^5.1.2","css-loader":"^3.5.3","css-mqpacker":"^7.0.0","cssnano":"^4.1.10","html-loader":"^1.1.0","html-webpack-plugin":"^4.3.0","mini-css-extract-plugin":"^0.9.0","node-sass":"^4.14.1","postcss-discard-comments":"^4.0.2","postcss-discard-duplicates":"^4.0.2","postcss-import":"^12.0.1","postcss-import-url":"^5.1.0","postcss-loader":"^3.0.0","postcss-single-line":"^1.0.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-postcss":"^3.1.1","rollup-plugin-typescript2":"^0.27.1","sass-loader":"^8.0.2","source-map-loader":"^0.2.4","style-loader":"^1.2.1","ts-loader":"^7.0.4","ts-node":"^8.10.1","tsconfig-paths":"^3.9.0","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2","webpack":"^4.43.0","webpack-cli":"^3.3.11","webpack-dev-server":"^3.11.0"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","gitHead":"838d8ac8efc059b8d669a5f6482203ce96db1f22","_id":"@appbuckets/app-router@0.3.0-beta.1","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-yPxFdONfY4CVdjIBllTzKxcslpgfcYdqc1zbU2DbbyWT8x5RuDYDP4N2Kto8GoWYRhSiJHAXia70gDBmVEGFPA==","shasum":"f855673a23dd2b30f067c1fc9a988006e4dd701d","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.0-beta.1.tgz","fileCount":47,"unpackedSize":291433,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJez9H0CRA9TVsSAnZWagAAzEwP/3eR6D+IXXtt4P6yRM2E\n6NPqyh14FwURSI9g7JlijLiFpRErAi2dw0bnZPsFKMHvfsZ+jWn/eXYYZGl2\nAEngTzjrENnZf3hJrt+pTlCEbAvLh2aN0HJWAKvO0dzyg41Qllg0kZVtBWHI\nGH8MLUA+H0o64hJ+O1Zhtg4N97Lnj0w4BGOGgx2UsCHdPaoNDx7Iff2jUa3z\n5oddUCTv8wO+0Wqjks8otUw6D8nr3W78GtfRLdmTo6AUnfBibKbctD96HTqg\nbcwfZmOjFfCnBNFZ5Bs+w9SukZI+NJOqFgUySjNSxZHubGTHQ4F6iwtFwVWA\nmWmEDzBGVnTQU7up/QXn/MUhLqwsKrnw/ZSpsA/BlmWjliiko+lTku0WSbR3\nQFqJFnLJKwIfqmIFhYhE+JzvP7KKYxXIyqpIQ5S9HPqVrp0DtJTTGgCT/hiX\nC8csp31rr/PWnOgw4kyghgRYKJ/iHdGJtaYqKZ3mMzDXkFgWqPTYenWWfd56\n5LLoHhKiM8IFWVOOQYQIUMVon9M7RVXjBZe9SZHm5Deb290h+n4mOaQ8xbN+\nOv0C1Wf7k3td+qGjGYFHVocbvRavg89IR6o6aEJJfnbQsQ3C3KLukWpfXLrT\n0keoss6R1HCxkjWGJtVqk9stWo+izECOBMg6h/QwsT7i4zX8iFpyDfLTHbJ6\n2v2M\r\n=28Ar\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHljpisabikLSnWM7cxToIe2xqoMZTW/Du7hK+J+8I2gAiBmWNBvD7PjdB5MFJ/FgFBxFSvy7Arc6Yq9RT1+VWkuaQ=="}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.0-beta.1_1590678004013_0.29224030155914926"},"_hasShrinkwrap":false},"0.3.0-beta.2":{"name":"@appbuckets/app-router","version":"0.3.0-beta.2","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"tag":"next","access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"~16.13.1","react-dom":"~16.13.1","react-router-dom":"~5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","_id":"@appbuckets/app-router@0.3.0-beta.2","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-O2SsDelqsTmAVGUSHFKwKhaPL+qYauVgrNqOnP2L2IAMLYMzvlYhfcRLdUff/PzBgb+swXrBynOGdUMrE2gtHg==","shasum":"04689c0c28f4ac398b4cd871bb9f0ab1a176a84e","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.0-beta.2.tgz","fileCount":51,"unpackedSize":247140,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe54RhCRA9TVsSAnZWagAAk3sP/j0swRviAI/CQOzv0jzD\nbf3b1C3Q+b5u/BnEk+NHzypd5VDPwgUhqjRW8XtFuHDb1pODIE770i+Gbrai\n+mrlMaQpw67OKnrfheTjIErTs0UKKtIG1o1MrWaSOokDYN5btzaLrlrqkcm7\n2EsmBxP1ChsASHW/7HS6BbK9Hm4r/2EyzDXtKTGy8vvkczSgrhRKLZkinOlN\nIGM8ZX9X9htqYzDV72YArCtVirTCv8LFNwpNDYs/Xmed+RttF/TROOFXUs9f\n7NTj9/ItC9i2AYcRooC4zv7u8AlMsDkRUsfJ1Znxg0jLuUP2ibmzV37cZ7ob\nVGrROyYZX31z27MVksny2/tS7YTHbrBcSrny9Zg8Gc0sIC1alNS6Hc/MWr+2\nEkXh7lmUGZ8H+ICY3OZ8Ws1piN3w9WcM0XxMusAuyWvpN/EzJCJDnHNjlFMh\nXJiiFT3sM/nKoG4zR/qApOIP18VW+BoasV2/sA+Np4WyK7kVj6VuGcYRkoKg\nSVKFHx4mt5jq4flLuKaEhJshIzpvlWKRs5l6k4przKV3jXbKm+BBtQ+Nc1lh\n+/jE9AAVmIWYJ2MhNs4frLukVR9OaCgSUPSh30w9RCP0h6jpw2Lt+ZLRaIVQ\ny0lsjejbL6kos2CI+EbE8z85NTDT0C9dzM5ye+j8Y7WRXaGUMvcjDoDBkzFF\ngh1m\r\n=3ZB7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD8sMy6hDB+gJzA216J95SD48xxF1Rxg3CxZlOnFYiFPwIhAIJTaEPHnoiWyXRJsVK0uBUDarBADHipbXD1ZzZb6Dgu"}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.0-beta.2_1592231009142_0.01359136871398925"},"_hasShrinkwrap":false},"0.3.0-beta.3":{"name":"@appbuckets/app-router","version":"0.3.0-beta.3","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"tag":"next","access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"16.13.1","react-dom":"16.13.1","react-router-dom":"5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","_id":"@appbuckets/app-router@0.3.0-beta.3","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-RCBLrbZ+a7FAF6ZBiYgQgoJci4Sh/Prq14yIu5upLJBl/8vGkR3uMLZoinIczW4BCBKIB94TTzPosTV0cyWjNw==","shasum":"3b856c5a573125200442d959b7ef4ab3e892a0ee","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.0-beta.3.tgz","fileCount":51,"unpackedSize":246973,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/KI0CRA9TVsSAnZWagAAg8gQAIQgCYsMTPWc6S5/BF09\ncMgwqQILL1yvSyakfBNT7cj2R050pEkkRfT7PqRy4YARd4RO2PbwfXDbHU6q\nMUSeQMTdewD3aLXHZPYg3knGWTPR5aBvdmPiZLmxO4/0MVQFNK2k8TRcz8U1\nOaisLJhEWgZbsLNk08xAfzzxja2mwfk6Q2U5eqyGPGRUI3HuUZKL9O62dmmB\nsQ5ThWH0sPy1QispQdGnpQHFVokhf7H3lgSwuaApEpmd1wfERideVlTbUzQ6\n/vvg7Fi8CW7skHTEdWMUG80fHWWrC75Jn/dk+OPA7IYn5JVRT78kBxmRTUkU\nkth+Jwu2Qpg8z2nzyJvttWlSRbzkD4K4bJqJykBTTQbJaekGrxMMaEZyjgbf\nMUbIR3aXqr6pCGrxosW0e83VNCUhZYe+2uhDi1mVaZC+GUwuoboAPJGRuYp1\nKOGPgwR3xfP2Gjm9C/phI+gmFz1yoUVW1CjTPxw0Y+a25gQ8is7KYULZTGyp\nxAs+0fygx9oJICuY58mkuYFtclp23pnKG1zG0lZj9UeUY9rdmERrBZQwhaxO\ngkcFcDbtNxdM/ZjJtQYDeMEZjAO9O/VvC+bYv6VSXBO8l+wefxSvRiEgJKJn\nIeiJ6URPDUvoOhRxk2FomGzXW4O7fKGpJYo9Hq/J7XgBaeUbG3Fy0lRvwQIp\nwRJM\r\n=6GrJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD/k6oMOQqVAPZKcyHIZdoQtck/NYnzKqB1lztm6rUybgIhAPL9DGjZJpygJorelNCeQjlycx5FNehNKIOpWqCPjhf+"}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.0-beta.3_1593614900495_0.11706160735568472"},"_hasShrinkwrap":false},"0.3.1":{"name":"@appbuckets/app-router","version":"0.3.1","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"tag":"next","access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"16.13.1","react-dom":"16.13.1","react-router-dom":"5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","_id":"@appbuckets/app-router@0.3.1","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-xzYp4VSRUFAYvmWmBpaCT45ARF+rWOYp8bOec4leLYOhCbpHHB031Cfr2qIbYOQSMN63u4jipyWi7+WnhAqQfQ==","shasum":"3a7598420460700ef070d1fab00b22dc8bd02c46","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.1.tgz","fileCount":51,"unpackedSize":247586,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/KewCRA9TVsSAnZWagAAIzAP/RiY6NoIXgNLfcSHmzu3\nYeQW8DEnk5wFKdwvq2JHpVDs4Fbn+J5fi6qim5Jp8gqw23tT22cpBnWlprON\nWTCFzo2FQgFXsz2A0CjWXTLzjkoqmCfxZ7uhorPBv3/12DKv52chNfPLF9m+\n4N9My5ci/gsZmlWl4ic1X48c/Mw/IAXNVRBcgeNjhlUaGR5x88AKC++7sDzK\nV51i6TeoYq2Zh0INuyF6IJWBVDBPnAW9u3pH7KyiNEQ+0Zj6ElyRzRtPMIb/\nRE9Y4JzNx9nK5uwdr72l0CzuEOkfgEfhTHSwStkspohVF/yagfxdqyeM7I1H\ntQyPLw1BNveqR8zgR4+tsgn5ZD/BeVXGa9X1FAUoWZ/LcVsAZmJPdsuKXhvP\neGVrATmlQ5qnzyWBy5HdR9AIM37RfysJ7NRuwfe57WeHGPHtLm/gDjkVn3H+\nWub89+FlFdoxYQL8ZdbRgRFz5mmAAwn03qUMzlp3cFB9OUuTRG0o4sYyb4R8\nhy48TXfmUBsiodYRKRU4K6sHVY+4QKUNwgMlZdv4P8kHreJK+TvVwSXWck8U\nr6lbboGady9sapJqLbASK6xAKwAqjzc/bHXuoN2Ax/LaKHLxba1w7qbuSGXg\nkIHyuc9YFEGkPYojilfrd9rZIGFDpoFulQ7S9d9gzyCoYNiTDhIofg5pNH3R\nn2nU\r\n=ca66\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDE4E2WIxgt4mWAMhIHJQLbbcg8iZEImZQQfaSSJAlxAAIgDgONjVOwFjK6OXpM8mEG1FV5EAJCf4hsmX9FCyAjHE4="}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.1_1593616303785_0.713046421213174"},"_hasShrinkwrap":false},"0.3.1-beta.1":{"name":"@appbuckets/app-router","version":"0.3.1-beta.1","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"tag":"next","access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"16.13.1","react-dom":"16.13.1","react-router-dom":"5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","_id":"@appbuckets/app-router@0.3.1-beta.1","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-YsTrplKNSTyZ0CBg7Je4fUI1e/3iHrBqLtOraqpdIceMoOqScGk7nc41rr8ZOi3S93L4p2mnnYDbDBnesvun+Q==","shasum":"24d238dc9543687d45eb79f40f4b666b7609882b","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.1-beta.1.tgz","fileCount":51,"unpackedSize":248094,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/MENCRA9TVsSAnZWagAAshgP/2fp31B/s8RUTS2LSLNT\nVSqwXyIkC65Qh+CjnPfdDl5NQ97D/2IrC9lZICGTedzqcwpjJ5xuWG61KZr0\nk9r3nbSvW+TbT6AlQtnwWwwRR3vvCd1bRR+0p9eG+ExUHRHkdqZVZ/I1UnSE\n/XFfm2O7MPA+Y5aZcG4yQ8otM6SVCHUuDKHjEa/IEjwb2VSbMhh0v/lx5QMM\nAmAD4PZHlfPLvSw/l+vmKaixfHIKvJOSnGMUO5rYQNlU8rhiKWtBIXCczPPZ\nlwS54hbAZXSynoucJ7tMQCrF14ti5EyMgOJfOlkOUx3KAfn+1JslOyd0u8yr\n0jL25yX+HxAKbmJH6ie1Mqh7bbjmtfqYeb+jtWfqzDcndkLOvzu3HtXiExW8\nmSQU8E+YuHsp4C2nJUyUhOsipOb+2KusgflQTSRr+MCdyEvK9QZw1q4ZEcNf\nv/ZMiKOhKIYwKDzXEj+hzwDOo6sqRx0rtE4nNu7JFDfgAQncGrfHMHyMV+As\n6eG3j8wjN5wQCWBP7LG3EEFgyKOsJcFMjYqq9y47hwUNLfUR10LTb7tMBQkC\nmgnpbBr8M9jjTDb/R7aIBXBc0CKLBQER6IR362qtUvqHNDBSXnVV9JiRKlh2\nmYxSpGgj/hhvDXwky+ydkRcHvQPFQ8XAHXdz80sv0Mc8NSewXe8yr6nwlA3f\njm68\r\n=HUPJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAl5O3lSBSOZqp6Uy8FtPpfNQZ6v7x06iGgA3DR9a/URAiEAhAP675l5h0xmkPOF/C0TXxpV11xp2nnQIxRyqy4BzDo="}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.1-beta.1_1593622797180_0.38418778352988325"},"_hasShrinkwrap":false},"0.3.1-beta.2":{"name":"@appbuckets/app-router","version":"0.3.1-beta.2","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"tag":"next","access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"16.13.1","react-dom":"16.13.1","react-router-dom":"5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","_id":"@appbuckets/app-router@0.3.1-beta.2","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-bRnnf7ujRu/r0+hhWZ3sTbr8gVQ7UwVZ51HbjgWEDF0tX/tsDiXocz+U7RkWnaUPZn4SHNvxOvl9JBgyqIKgQQ==","shasum":"19a6fd6825cd9e8eeee40d00c0c56ecda5370203","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.1-beta.2.tgz","fileCount":51,"unpackedSize":248097,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/McNCRA9TVsSAnZWagAA5uwP/0klPuc56iZyiFYwkOyx\n5G4+pO892mvi/Qcoqm4OHiv+gqqowa4lqpkWIegx8k2I073aS6QFP6dscKDd\nR8kVE61V+GU10l2m42NW1loGeKJelRm0UvAy4POj6Tci39FHkj4d8q+DMMDo\nryHsW/8d1z5A3ek2mKIKiytnfdYdZH09Ll2bEGnhHRLMyvugkTipRoE5pmuL\nOx9ufVlCB/N9avjrWACn+ERpN+0vxpItLZAj/8q2nWQ0QfJQp3j5VueguQok\n6Ev2RZ5hUp0EOfHz1RMKBLsQTnvD/T0HUQQxDIjaF7ziahX8XigiIcNGsV7Q\nzG+S+Pnj3+G0YuGKsKQHInoOlQgGA3nAbY8sD8cUICrgeD3Vo2SnZ1Rw6T2y\nmQLen9VbxDh+Z2+ppEVUhpAjwCpXBBGYdS6tirlBqAULAqNXZoQKdaLxeCkG\nsCK4C1DluUOQK92UqJSlflVyBz4O5yeQpaMuKZFSkHxCnXbPyjPVoOzs8fuD\nxi51X7Yofp8UvMSrzomguRLzSdGVqOOveP2+uT2sw6UEvkRT0LLSekWUSQFL\n+7nxJg0iFOW7mbwpIBhYM5YMj9BjrZRTSI6zIazzN33ksoNiJezO5m0rQsOH\nNT7M754wkizDQUXIAEGmRUN0Rs1UuLQZt5x50E4ligMDSHnZJFzfZgCSWuKo\nW+8/\r\n=EQdf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBtIwaFX22o5HFhp9oPGgWytOSOiAbcFJOjz3to5DI3WAiEAuNV0k65FHoqV02aUgkVgl6ByJKY0vmMLEJCzuMKali8="}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.1-beta.2_1593624332773_0.9106351310851044"},"_hasShrinkwrap":false},"0.3.1-beta.3":{"name":"@appbuckets/app-router","version":"0.3.1-beta.3","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"tag":"next","access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"16.13.1","react-dom":"16.13.1","react-router-dom":"5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md","_id":"@appbuckets/app-router@0.3.1-beta.3","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-NelRYVY8jnmufCLK5BenisSDIG4RK6THmhLmzPhutVNKotTgLtTNO62VfRc22bOe/NOPi08n+6QRaAQLtQe0CA==","shasum":"f9ea4e8e6ea9533d723eeb6ce69088f1aa0937db","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.1-beta.3.tgz","fileCount":51,"unpackedSize":248146,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/a8FCRA9TVsSAnZWagAAhk4QAJm+HF0H4cnMk023HyiX\n3qVZxmX41C6wbwSAFUausWN0WDenoYwOx/PCx72X3ej0oO/wfDJb6lfdmrmc\nOUoI+sg+ja/dxQ60gTvnE2kBCSU43oRES6osLTQaU+uCIZPNkNAehHwAVmav\nf/Sx7xXsKIJqj49hYOC5JqBVglgxp3a/SU/OUnz+KSo4u1ne5jzzfIBCPtiJ\nYQ6y68wwcIAE+5ij9AazoNlNEIQivYnifO0NYSPeI8lFKFzTwNYBuWse3wze\nx/Knabig+LZXsK1/qWFvJNkkvcIp8I/m2wXZQ69QO6vrSJ2YGzO72TwG1un+\n6ikbjkZhTU3O3soaR9gBRMqFzHGF//2KFDVA21wNWSm2k2leRIKRCR3SOIR5\nOEhxlLoOUGShovHCe8MdbtZ7pbk8yzGVvc3DEMIRU8vm90fzZmaYf3VAcfHj\nzSW63XVc+LCum2G29RPsHqMZsfz3XBWUE1fqfVebdgZV7h3sHGcPVuR59sLt\nyZX7NKp1GzYuYmkoMjbSQurUZjpN56REt5ilzaBrfVcsrlh8BIthVmI40L7t\ncCWXcAYZyfZpTqu2Zlb5ElsDB9jPLqYiqvQfFrycgJfcAdVDJ54Vlz6ru6Yc\nBEIn4bTNAcoL3gL8LwjLXyNdhlJKjP/ZTxr4LLuXxAywa0lLq9KmQH8nI0ul\n8xQT\r\n=1hfL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHydm3i3X+29zHCovzW8wh9Fu5QoDdKqyonm4Cyc7C7FAiEA8YiDDRHtflstulC+30GuoC8+3RmN2v/Ju2MtCFgeds0="}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.1-beta.3_1593683716679_0.3691648121753326"},"_hasShrinkwrap":false},"0.3.2":{"name":"@appbuckets/app-router","version":"0.3.2","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"16.13.1","react-dom":"16.13.1","react-router-dom":"5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@0.3.2","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-kKxP+O+Sl3jti0p2yPwt/ts71eQQPrUNPhPC8UB/aFMfSrIJMyc7h8VeFP6ktJZoNh7SOqVjoaD+Q4ppOZeN9g==","shasum":"2bfcb5a23eadd9bac3db6e026f744e12d36f99ec","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.2.tgz","fileCount":51,"unpackedSize":250585,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfF/qXCRA9TVsSAnZWagAAwsoP/0RoHSO2YfEuJzwehbt4\nL/oJzKPgBpJJa8O7PjdrzLwq6uMWnMcB8bX4raLvZTDgqdzNNLIKMB6uv2q+\nOMfrq67zSU/WbF4vwvFUbC7Mhtj63hFyN2qq29zfxDO07N/HHKotQRdJUXbs\nmnyhaZ0SfF8PPkfGFaxKkJNtRL3Ls4iwUTBZWAWrQZk/wQKs390thUmDFlSo\nEya/DHIjrC8j24i0ru+uAHfJe7uuBeO8QTZsuEdsUybN48uPEpDur6YwV0n1\nW1xje1N4R6rqVuCv8xLehpk18iev8PNfdALSrs21RfAKo4aMHTUMc3ar7tlE\nBr3aSY50+TtR1hCnyzeqyOH1MV8WJqobXWqcThOeyAceczgLk47x84CNv/7b\nf6dabWKEhxSe9Tt+c+AJAtMi1Qmg3LKSws4FyIfbMng25EIzkkA4QJKuIz7B\nj94CVS6x2RBSUNi7TfbQXAwvFgMp2Q7zeWFGh2OjUBKy8SqRpB/9V7V4FVyM\ndHIlsEYPxcInA0nn6OSD0hUuoPqeRWgGeIkPg/LqCozB/n8UkDkSQDdgsvzx\nho+mGMpjOStjhF+/MmqQe2mO1g5COPCRzXwu3V6/uk9oWO/3D2QA9k2SBcEQ\nD98W0AFkyl47NavLWn3KfXRtFxf0Wn9YA5L5+R2L8HedjWOUrj+HNXyKgIl7\nE3jm\r\n=f2Dc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD4uTzAaW6EQnwy2jMJ7jjRdwBO3tNENzsykH9z1hBXMQIgHYRfo5Anw8r7aXAyN97GyHaqAchX67XFcgzJBir5DmA="}]},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.2_1595406999110_0.15984718093434913"},"_hasShrinkwrap":false},"0.3.21":{"name":"@appbuckets/app-router","version":"0.3.21","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist && npm run lint","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start","lint":"tslint --project tsconfig.json -t codeFrame 'src/**/*.ts'"},"peerDependencies":{"react":"16.13.1","react-dom":"16.13.1","react-router-dom":"5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","tslint":"^6.1.2","tslint-react":"^5.0.0","tslint-react-hooks":"^2.2.2","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@0.3.21","_nodeVersion":"12.13.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-q4SbOLIAR/e6Lk9n3bTeX13YlzIrvCAjWBW3vIuUr4RwI7t57bAG2tskg4Tduf/QabnESAipKkyAqL4QVT5oXg==","shasum":"d1354b665e06bfced8d58a686c2de5334e1b77a8","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-0.3.21.tgz","fileCount":51,"unpackedSize":249769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJftW58CRA9TVsSAnZWagAAZJIP/A3kZ+pndf4tJ7SV9te9\njgRuH3LdQxG7H/kx9rRpF39bnlkgMw/rHYufIOO9mqRy4luYKCKj2tTyoQns\n43lGq2i8EPRwpcDU2V54vgnKjcES4zVc+H2CorqYLCNoM2/zxuRpHabArJDG\ns5kp5EXt8vtd3a7dOa99dhIKmLF0cwUkYSI4vuCH/a1J5PbbOyT87oMGS6xc\nWG1kvJTGGdNuemP0WSF4VKs1CWu6spidRMkHHLXWi426koBaI3WOwupEeS/X\nq3b8fhEIvXw1ire1pErPSFJxkXJksTNwPjW9TzvDF1ECHlHVzd+OR5IO6w38\nj3069J4O/EuUjWwZ1fVZ0tE0SVwX2vcsB2qbIIlQfOSgJiZJI3HdlcEIiVpf\n9JmTHx+Qb/w9V1v3xAVLxR4jpV+9j5Rf4U5SQlqSw10UqJeirC5FnnCMVnGZ\ne8B8wqBUJY866V8/m1wcbdoh/YRd/MUL883vukBDxIZ4ljz4Unl4qCg/p106\nDqR30gnmpZ10hnq6gea+emsEkI/JpVUWbQzXwflVnNLkkyeO3AXvXfRXs9dl\nLVHimBRAO4CRZziJPnsiQSJI0eePcp+swycmNJDRx27dDWUZHqU89HkksY//\nsmRDYUWExdMRG1QYnervTppvWX2OJw+NnFvxWil6xokMqSI7/Z7l26KvsY0I\nho1+\r\n=10oi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpx2q/NrboO0doQnONwLkWBEOfCcb2HzP3rF8sgfT0dAIhAOGcZX1rRRcIsiWeJATu0GpYBsEx7yyEreDGcJTUr3df"}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_0.3.21_1605725819694_0.5472109909745906"},"_hasShrinkwrap":false},"1.0.0":{"name":"@appbuckets/app-router","version":"1.0.0","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"node scripts/syncExamplePkg.js && npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier","start":"cd example && npm run start"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.0.0","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-3/3LnNDDd1qoTjtF/HoJy9iiRCV264LSVyOEZTgVC+YsCYePGiDOnOKRmWC/XJ+xzYvZE+2EHAZDJQ6WAjRY+Q==","shasum":"f054bd380844bb757952cacecb0fbe449bd1aef6","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.0.tgz","fileCount":79,"unpackedSize":235362,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzmbMCRA9TVsSAnZWagAApVUP/0nSm6P57W6/Z3ZN5oeH\nyD8epKMTJyq/H219Ywbm3v6x3c550kENWFYAQmR1v2NCKwQ+mySZUP/CTS4Y\n3XYSuQ2c+asxw4Cl2MIwy63QIaDToIyiKfh/LmEPoXFLiu1gvmhoPUTo63Jc\nE8Ig/F3CEswLfpxeVcFFTCRSSNCs8VIi4OXB7i9/GVf3GuKx47DJ1MyviAVp\nUeEW9AuqKapJHbLxquIv2bpWa/ZeEgHC4elVhKdp9ot5C2JVidC28ZC4MB7T\nm3kfW7tA8+39nSiKqU16ygOmRFz8VmBK9IHbAOI9JP8zZhxhZFkUnoBNVMRB\neF3xWlunm4uEQviN1OLVTqfA9OCso6tj1tDmLuHxy/BIDmiJBtIn0QIIKMvc\n6l0H+V3zQNlxoH3PG2bv4Ph77Lb2oeGkqNjHv+GmUVm3L86WVngYX8zc6ocS\n1FUD/JL53XKLnLhcB8NcZRRts80Nl/5jwkfuqZeDlgI77Q91bVB5X+Y51vDW\nb3tH0gpi56YDwc+QYlK8JlwVbOLjaa6o1DsVAIjwakJnCv+D7UgZ3mF1d1bh\nq435ybMQxEXGMkct9Eivb7thaqwnQd+nQY7jyhLcQ7kXxqFQBApCVg5hQX7I\nv1k0woegmmCgokXz7XgbdmI72mGZ/i2SZCcvlX/IDnc0R42/BJ6FOXvcvKyZ\n3gwe\r\n=VZw5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD7FaNOuOGozLS0ppGfjQ/gZTxD5/y7imYN39R2m/C4lgIhAIdqzbrAod7x0WCBTxvqsUY+nWhifMOxNX6eJQZNqklb"}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.0_1607362251986_0.08258025833359528"},"_hasShrinkwrap":false},"1.0.1":{"name":"@appbuckets/app-router","version":"1.0.1","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.0.1","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JK9cg79pbfYTFgm4HfhFbDTzqPXR1Q75b4bZoKKN2zsuZEXlxaJo71RJTAZJlnHzHywRHIaDddeUGRMgKj1esw==","shasum":"59f94bcffe15b285fecad6a121c68728db6caaa6","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.1.tgz","fileCount":79,"unpackedSize":238416,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzm5ICRA9TVsSAnZWagAAnccP/iLjzSvUkmsOXSiTVIFq\nojwoonnRyxEdPlldsv4//XYTKpEc1H5B8yTsQjA4fdXTJcc20d53d6UNSE7/\nRHkcas8thcaiG3JBLSABJUelUtHJ/jEDFJxozC0cAJY5TQBsMqduxNYPCIN4\n2dcAfhm9InmkE310IIEObXP7V8zoeHgz1+DuGbDgO/7D9nw5U4HzjK64xYf9\nr4e8QB56fl/QL7FjvUHUVjDv60XXUbYOOeMQFLgxP3XnlD+Ey2/K6+pKUn+O\nWm4VpF50A9xygJzjeMA9rx5rIl3sv3/vbsfJdGTFnJT/mXfn35zo6Yy+1oRO\nP9hPqhcEYpX7DYMjcmH710U1eUtTyJvzhUyO4lxNZs2QmskV/rnjSnGd7rsA\nPYGJ4TZVzk7ZLq9oP8ZFHi6WFFspKcw6cdDCOgVWY8rOBrs2P54VEtvVdFGJ\n/BGuIAt00fArqdl9FksgEbvVMS3nc/Xcf02FPhQUw08vxBnDYLF/N87PI12j\n9RNS2QZnO8odBH+zQTO/a72nBKEWZmn39f5XGG3Al57q19mOLPEqL61Cj7pt\nBd5gi187Kuak1JkmW3IrJHQ3Iyh+pmCkQ+NtAajg6ALFrkQQfl9ySBnjEq+v\njrMcsyaKE2MpDIFy6jxtNjkGso6SA22VCcFG2c6NUB/tnoSQbgpOUrZn1ATb\nS/7/\r\n=GjSY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCmA9PdDGwwm1s7asXKSbJtUru/s/YXdaURfmcrMdsifwIhAKqIvw3Cyxr3QX+nsEtQNBk0nlvkgr1vOiYqpqckRWZt"}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.1_1607364168215_0.39094271800991676"},"_hasShrinkwrap":false},"1.0.2":{"name":"@appbuckets/app-router","version":"1.0.2","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.0.2","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-kbMdfI9EQiXth68ewxEGsSy11HYD5PpSOIUNvj9B+tKcqRJuGFyb2bO8BNa/vG1a2PlF/EV5Lwckku+xcOvmsQ==","shasum":"1ef042c9648b5166547f7c6bb600eaf1f643d3e5","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.2.tgz","fileCount":79,"unpackedSize":238240,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzm8aCRA9TVsSAnZWagAAZDAQAI7MDQOe5GTNZcLpkexH\nNJaulnRc3F7q7DWsqxm2bkG36Sn0QaaCiegwkHgqKNCzMGY7ZRj9eIv2Dgyj\nEaj9ZWRENKhCEfL2lqwu0t825qNrqNrLEZrHMx8e2X01Ol+RP0mSN3/HXlOR\nMsDtm6KeBaDfO3LRAGrH1nsNzTJyuNeJ6YKUMfJo7BHfH1PT+agGau9HGUx8\nzFlBuHylhFWBKORNdhqhfsQzMafQ0eq5Yeai8DJS+fZS2DnWBfAqpYwDS0e1\nCWsbv0JbQMVAuNUxMV4YmiUB0s52HDlokhLV/doXBn8fuYVYvslzNJWTK21c\nN7CwYqugarVjosP0V3KavEIaY5ROCm9RTkmpWRpgbtjC8YKb4wJI2/EC6SYr\nrJvNhUpVvBZVHaut/pZ7qhA4VzwYxww3ahTEcJYWEQ+jKvKScwCXbQE1Ikzq\nmhLRvcmP3w8+d2tPmPlw6sDt+lCFsZwOnNmBWkBhyIcchvj4TAcUxFwoOHA2\ni+AxUZp17o1cC95J/QH/5DX83+X9NO05A62+vgizL4cddXCaYWmUbJuTnYcw\nCC4h9RWwcy+V4NrSNA53Sbhok3locKqbYS6T8l7/HnWrDLa8lIM6hzrJ5v/3\nYLU1D2vO7u36u7enzLyeuh6R31wtU30AA9371oxn2UhehwMjwsRVY9RkjrIz\nRl88\r\n=NsfK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPunoLC44Im18m6TcAL0pyNcisYAlEd7grJonSyb1rYAIgcDFmBKAHggegVQzg42psVFWDyNY5zXN+1Asd2mYT9og="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.2_1607364377907_0.3676963194217042"},"_hasShrinkwrap":false},"1.0.3":{"name":"@appbuckets/app-router","version":"1.0.3","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"11.0.2","@rollup/plugin-node-resolve":"^7.1.3","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.27.1","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","recompose":"^0.30.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.0.3","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-wQFUJMwpDPk3+CpKS9zgK24OsxA4e9a7ZufN7KGTzkjEvkDeztV0hIv7bbjjoNSgnBDwCwZqt7kt6qV+yP3UuA==","shasum":"a157312f470415c62e8636569164484f5f455ecb","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.3.tgz","fileCount":79,"unpackedSize":238122,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfznIGCRA9TVsSAnZWagAAiA8P/21sW30rsIGttuhyU3Kg\n/FamWMF2KbFKyv6Q6h9Vr4QCGGbZ1gNc88GPwd4i5q1OzIja4wlGlFlUjSMk\nM1Q+8COf1gXlYubhg8WS71yg4DELPfkarvyJIhkKYzTVeoBBPM0x0PhwjeZN\nq2K8OakMgkdHm3+55iwGo4ysP+SYJYROu07QhZbEfWv5tKZZ1pQ56sdNksZI\nCM2KlI7UXBpAuGHNE625bxxVlb0HfP6j2RETW6Ld8CFaKGzYGdmbhC2/0pUw\nncTCAzk8y4GcQdEYwsJjuXpAFgUxhM9CcIHrpUtblRbraHUoo72zykbfmZVK\nIWf89lw5onjHppiJXHxB2oDxiJJbN9N1Rrf1LlH0INrc18ijaFkB95XqK2fw\nbtSIqQTUXjDC1g2u6vdDzVN85QpOQ02O036015slpDt1e2Dfod6Zn7CVPzRu\nCYrhBr/w+BPJrAgJRG3+tfFIh1zf82NaDpfgFRdVMEtrXcnQGjmL3mv8492S\n6f2kkkhDT9sZ8PFPHEvgQ+EPXK0t2NrI+Yfl9ww5r5KO1E+ffe6ok4Fw7j/t\n2re2/rWuEsRV45/zkXZtdCahjPdue/pS0QYc3BeA1zNRgiJbUZRVQqI5snB3\nbdHw3X0d266wsdkVAPI3xKTWLEXmxMsCQSQ+cDE0scm3V/H9xdZDeamF2/pa\nNA0+\r\n=ouvj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPr2sXgnLG1Da5qbsBauMvmswgumERegpcuMbZvkdDtAIgKgGP1RxP1BzoJ/BdRcwpCR7dl1JqumaW2ktJba3m2bs="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.3_1607365126505_0.6332718162797961"},"_hasShrinkwrap":false},"1.0.4":{"name":"@appbuckets/app-router","version":"1.0.4","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"gitHead":"a2d5d7c451659d1367fb31a69f483d9061583959","_id":"@appbuckets/app-router@1.0.4","_nodeVersion":"12.18.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-fqkti6+iL2U0VUQ7PKUb8tDTyLgya5tDrKNQUhcHj0J4eFzo/OLhHC/dw5bJ5Dh8wBNvvV4UKIMxXTjpt5IXCQ==","shasum":"bb8b4b730e1dd4f70ba5a482c910e805eaeefc81","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.4.tgz","fileCount":76,"unpackedSize":233301,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzrHjCRA9TVsSAnZWagAANvEP/RGyBABZassHwnlzRd5c\noQw9fEUOWRAcILLymR60nscFiyHon7xhH3+X4DaXFlmCCRbqmuJ55QyLINye\ncNS3Q6eNrCAgjAF+hinNdfdrQu7eFLPs5JdrsfGUsGeNLQxIbR3odMs6FUAm\n5QCXBbFflrljB/KHIUbir52eoPmUuYnUrRi0rBCnmlf2NLjnUUR38VlFYmX2\nw4RiUe8IRCBJn2pIywiZ1BbWkaP2CpHIQXcdVlZp4heq9nTJRb2Jpp/ABtI4\n9lE7bRQNlr3co4mM35lBuzIId2W6jdxjOGh+9nU4os6KjjHTOSC54S+5Q1A+\nf+LZgUWddsus2ljc1Sz8/ae1HLww4MrdI/aS8lhGTqZH4besc91YrwV9kqcA\ny6xwiigoGUQFIvLES6Lv4KFdi23ZXjen5xvKk9RgsllJF4M+y3lEJT4p+WQp\ntpc15TqCZXfixaKsgYfoBHFTWPLDwbrAAUFbl+N8ueXdMnU+iRmXqhA8e/Vs\n5RDOnZQ2wLWxmuvDIu1Y//ctrc/p8WQdehSyTw90jY9KvDUmVnxFo1zZa2un\nhzw5HYMQQmI084J8t6IUCU7ysqDaBbtYXAB4quxlJpb/CIdqjltAaRZWFIkB\n82PpdHDI55jF7HEWVXkQ7Tx6mG62lWQ5E6ozSbV2O4aOODxt6T0kynvHnaYK\njN2E\r\n=vu1k\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGFvBf4jRUUbO3/4YXmnLZga6WvdKGKnNJCJH93n0tixAiBpAXvDBnZA8iW3cRV/MEWoPOxzVi1szy1kkmAmyYz2Tg=="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.4_1607381474747_0.4749323825852192"},"_hasShrinkwrap":false},"1.0.5":{"name":"@appbuckets/app-router","version":"1.0.5","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"gitHead":"b84d14481f5a199e2c8f80c78a386d7a68c0f9f6","_id":"@appbuckets/app-router@1.0.5","_nodeVersion":"12.18.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-KtFYMKMrvspUtEmCkuKT6FEg4ehLj53mVzo9LSltSVOScWdA1XvXKDXT/WbLvBt9RYTXDk/Z9bhZOiUazK3pWg==","shasum":"53db69dd8af8411b00f500997cb8124891e4a5a4","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.5.tgz","fileCount":76,"unpackedSize":234241,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzrYKCRA9TVsSAnZWagAAnfYP/1u/njBSA6WfY3FDQOIs\nmg9TY99giQsvprmQ0nkYuoAnIBqqs+xZ1nKSNjYt9X6fOQizwS4nATqzBXtX\nA1Id7vQ4xvgXggnrBjgW8RD4xMpUX3C1gi2SNePmFqCYBb52XzKZ7VQSgj1O\n3Uz9rA8sDk9J7+fmj+cMa9quhF3TOWhHdfhSWpQUqAZCVxQ6lsg52JZaJsrr\nQXye00ujRn5nRmWmjCDi6IIpxdHs9yVe42eP3esViY3D53jEJEmEwox4r+4f\nIgnU34xemZ0AiMRsXgeXB0+3xmYNsmLB1mBW/i7Ahenmw44yRmY0dFouHVdI\nqYr9068xj/Qf3oaCQH5fjTvrxozhXEyajNHXA1WBAGzB3KDua0BnxbsfeAZj\nMHBZWpzRAe4Wr80WP8oM3BpPAXsfNE/6bM/ErmN5b7IvwJ+i3DxRE5TXYI5N\nN8Z9ETAh9giM3UF7DK5h8pjDIZFbSrwRm3bT0dziU+Xl/Y7icIEGtv24p2E5\nnVzN1yPBdal2o5zTilVqxeuUkC9bYbglPisPh7+jYZ8v0PIIzGewYmRXKv+V\nan8h8zRtpORTujzzYAJ8xsioBlDAT1yCGNhVH6F+hqGawTuCG4bgniujYSbL\nBrHhhHDx+SCO0TFrhY1pp3OJGLyRQdUgnwmsbuVmNqZrRWzcV1D53n63esuK\no0jG\r\n=loBk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYVtDilZoDmQT1pCYRyFs5GBXFytFngKohDmjT3tU5agIhAP5eLsby4zAizdxVdDkZJpWtSTKvkqc6EJiHO4iB9/g0"}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.5_1607382537715_0.11504019970974433"},"_hasShrinkwrap":false},"1.0.6":{"name":"@appbuckets/app-router","version":"1.0.6","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"gitHead":"321473382a20bf6e3b66c4582c23638dd4e91362","_id":"@appbuckets/app-router@1.0.6","_nodeVersion":"12.18.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-pouibboPcdnxg4DRiV4tI7IkgV/8CvSVSU7m+LNuwexzXnuwab6DIh1r/FW8SSkXMr1aNytW5D7ye9ley4/Hsg==","shasum":"9b079262f15c490be72e4d55d5296fd387ab1bde","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.6.tgz","fileCount":79,"unpackedSize":235849,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfz/KvCRA9TVsSAnZWagAAcXkP/1jNOdyKqvp/mV9KIGZs\nUNJVMy9K4z1PaAVkKl2cSqTS5D9rzR7yXDd4IGmU5S4/7ctPizWevbrXXB+j\nbOIbi6o7FTKSilw4YsGtytR8l1x7W9M052pPa3+wKAvAKeg1NNVRwDLuabPG\n8SYxZ4fYnxNOG7olF9/7Z4FZU9mjcBPHZUigJaE45QrmCCWAzqI4xRvs+s6z\nfj8/N3Jxq9PPputTiFAgrUN6HjGkqhZrjJY8X0ITRtk9E3LV7uxVjmaXOMaR\ncvOfbk3kWsiox2M2DxOePmzMo4aLo4yNuj+GUSbcoZvFcEI4/FHDXTMEhr2t\nchh9HrzIQmg3sj710aymhMKa/0ZDC3SSvV7IhaT7vbhHlpLDm5D9/vO3G5+y\ns0cnwg+isU6o0wpFN9sRluF71R0JDjSJJEHbb6a1LNQajQq1xYr0lSjQF03G\nxZB4J1RBK5hHjvrhfuW23oUrKuRNLrlTarOw69mc4BO0Ug4Hf7fhfmW3N3Hh\nUOo0OdDmSGsxEaDSGvD7hbaHuklzEBQ8VocEOyQIIoz8URt/sU5iNgBU3QNM\n31XbMKWZ2B5WfxFJbfZlS5UTnl6RsEx+V4n3TayxvUDtgdHZcHbHcYjPfI2m\nUn9axA0y8mcjPcxyfRJR9n8uAdbxzMpiOdaGpL8cOkWj4/N9qZU07jyeGNKL\nbtYi\r\n=Bvza\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDzCIWYP2Q5RfTyilVCoBZgLBkTdyDrcZH+k+1EWKd22gIhAOOrqdpuswaQdkT51hm0x+X20N/V8ThxNa4mM2eq2oPA"}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.6_1607463598979_0.17302943848091323"},"_hasShrinkwrap":false},"1.0.7":{"name":"@appbuckets/app-router","version":"1.0.7","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"gitHead":"5e0a3f2a67b74e24d1dd58cdcdbbebacd500de2e","_id":"@appbuckets/app-router@1.0.7","_nodeVersion":"12.18.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-wKYWda/JDde5NX45h2slL28iMv0KWwWmGWZgp4La1aVvvL0zibrbKEJP4s3JVf/uVYz3kd6gg4uzc0F2fPMJSA==","shasum":"dc6c09608bc4dc0fb582a6a63b00a82ba15cbac6","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.7.tgz","fileCount":79,"unpackedSize":235848,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfz/p6CRA9TVsSAnZWagAANY8P/RJabYrT6fBBRE6oBa2n\nCShaN4VU/sYcF70ppVBHK5JzdkdXkfhoez8Xcy5YpNMWhvCqJIiAJ1KUkvPQ\nUsL3RL9/GdJin02TipF4yLohUPYdfG4o5awNDW/u6e7CXKF7RYoz8txAJ2jn\nq8nDirVvfT6Xdhb1QVIx1pVweMqknwmTCAyQDHY1spB1KnT4//obHZOQkcya\nNAxqyi8/w573KE8FYH5Mg6l8104/fxhEWOCLtp61yMHDPA7IocotY+uxBEm/\nviQDVikodDIQoYctO2IiK49BH61nUroWjfNu0bmr2wHuIRc3POKwR2s3eQWC\nXXDnnQKEQqqUkyKm2yLMBKetd+Nq7fT48dTYq7irRqTwfk5sk4KLTlmyDTZe\n2xTESnGG7RtZZ0ABzu8FRBymDlf3dEt1mCr/N7uFgRQ1FcQKjlOsIvLkPO2B\ngtHMtpoRLSTCM+YOMCoQzLZni+nUM3GM5vrzesIGvrsa/nP7yukkOJWfFbkd\nEb8lLDoKmr1Z4ZwHNTouCAGvYRtxGeMhHWdj9f2N5jRz2f1qe5xwVBvS9/tD\nIBovH7i57XDC1Ix9jrBJd3PksXO8mT8Jzp2wG7YDp39Dv3HjRMRVUzV46+wJ\nt0ZtAZa3B/dugMSyZPi0cMDwsc6uNVTkbuEi+m+s2YgHETyu3ImoQ4D+fIy5\nE8FR\r\n=4lhM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICc/Ur0jrxe8BXOeiG1g6bgUyezIDiZFd6r6DrGJXDGZAiEAz1TwIN4a1Ob/tvwpWhYlEHoPZrqxOaCgLMg1s/c/so8="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.7_1607465594044_0.053578262332633964"},"_hasShrinkwrap":false},"1.0.8":{"name":"@appbuckets/app-router","version":"1.0.8","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.0.8","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-d9bdTxy2aXDqzWDPMkEADWzA4weMDkAINZKYUYAO+mw/9i6kXgCFw0beI1cmCLu4YUF2VgmMv8CB8bmfTLtqew==","shasum":"c456b3c79321956335f698f75a7dfbf61cf379df","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.8.tgz","fileCount":79,"unpackedSize":235848,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf07X6CRA9TVsSAnZWagAApv0P/i99P7MD10CAUDcE7zre\n4V4uyyc8Ry/hZJkM9wNIh/fus38krrpAv/TkKDEbUxiyafJvvfT2vbfs+BGc\nL2OrD9hLe9nwWFcwJ5TlsHSHxAApbA36kDVCf5SXGSihx7d0BA4daKF9R5se\nT//YDLi+YzpRkC3l02JlWXNsTQM+FT1+JZY95yrQssyl+zEZ36Vpa0oTYlzg\n2ifcDB395OI+bkfBugl40k7zXklj3sqjlfSRGXVxUIIV+VoaO9Fp/NLfFjg8\nxPAt+LuQh0K7Unb168+7bGcNioZE1Jdr8Cq6r0eedOkqrXNqwgldCidVs6rh\nCfEfORvy0rMtDj07qARqvmtHZ9VMInyxpjNs1/HfBu1X9451HNWXTG4F915q\nT8y0ojZv5AvU4pgYtDiq6xT9/S+c9VQs6xFZZuvzUBTAD1LYGYXQOpTuYLkt\nkVuz2eb8HzwPEXMCRJxyPKaLs1fVEw9muJOEgjIhJ0j6/9jSFgjMm4/30Vlw\nFq/1vLWOt+bLJjWjfvx04r2M9R4exSWJXG7yVQjdape5tykmq+PXpmFUB0xC\nflPfXWtz5MtD4lQLDpjhX8+5RenxGVUu3hw0FAQhLcpnrO+Thb/tvUN++8fH\nKMGG29iVQERJt9AhSKQAGMOdAIwD6zfNWxWAwPqMZgU3Ir8sdZdkxVP18Ndg\n8nzG\r\n=WFeB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCsv7HEMw0hv5oSPMtcR9PBMxCzg2v3mNx9EhbdpR4vwAIgF7zh9LzG86CGfmaUQUjQ9F66q5WoomNOY3bUKwwcuTk="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.8_1607710201501_0.20777171482157875"},"_hasShrinkwrap":false},"1.0.9":{"name":"@appbuckets/app-router","version":"1.0.9","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.0.9","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JycYU9o2p/lcx+QNAuQ+fXyxfErouWA4RRbJUemFLnrpbXnFkOrhpuh7pT8FZKDNEspP4SIdMOzNsyn0rsD3hQ==","shasum":"398db36b62b5fb46076ebf37ac5b7ae4db8b8dec","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.0.9.tgz","fileCount":79,"unpackedSize":236241,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf4iqDCRA9TVsSAnZWagAAj6oP/3cTHz2+9bxH3cmXKzfb\n0W10P4DKOrHFsVsjMluc7e8lSgkcR2d0CZtIKNStV1SOQcfFGfQCcepoboYf\n6NfiNwyE+o79elBy+Xx0AS6XHSDWbkOZB1aKwy+W6aZtkNxYDZwSnYhlwctb\nRbzBwNDsNEgq/m2dKrhb2gsToz1AZyiIX9/9IF2EO+7G/gxydNEKPukWp0iF\nDBiNq7WThOYBIYtfYyIzbrrDEiIagv9kX0u+pOa/PRTaixdCAvpmp9LFAOQN\ngZJWsSfynJOwBfFi+9FFGCLHDRtCTdrmB18SIGmy0F8PqJzqDjDHw1Lu69Jc\npSv9qQvVyXgfqjJwb6KVo9wks/9PBbKaB3pv22a3K7c5tNk68nhSUgefM+jX\nTE9rOu8wJzBn2Jfd4sYFjdrp1w8NUeHgrv0qsoFg9pr6atVOB3JSXRRYT8Ee\nUjzZzzJiMdyqLtbFB+ue9urzUiApf3VQ/pDtJYTfzbP2rTBN7mmYQ23yVFeH\n68zweiUqgzcn8kBI0D/683RMvA5jzkP79LzRTyEkfXEBb1YvTdCCKisD4W7Q\nNug8lWGTbIl9LMQONSmw5rmbx/djCYbDG4Ldt+yyFYqkHbjO3cZ726ycyvtY\nQliLsJR3DQ+7STKGfcYpaQUCfQI/TR+R/A18FgdUxxhTFG/kfrYQlA87UP2k\nh1HK\r\n=yBLK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHNkwY0mHSFGYy0PdDpbL73qZEPjZv4hQWxPQd59ZPAeAiEAxgVfLzbjI3eqcvOQcJ3qAf1+a6jmEpxIjQvXJZ2R9qw="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.0.9_1608657538756_0.2352208738528785"},"_hasShrinkwrap":false},"1.1.0":{"name":"@appbuckets/app-router","version":"1.1.0","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.1.0","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-MyqszyNw/NMyqLlVFSfjXrpHt+FiQ/Wgy88jfPXRL575aYZHQG5ygiMbrtdet3XgfF3qabWteRblTElnDChzyw==","shasum":"a7fe3183cb5f5c3364a1328888b7ed8a62785fb3","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.1.0.tgz","fileCount":43,"unpackedSize":232973,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNOeZCRA9TVsSAnZWagAAuRIP/jLxp2QQLoEg62l4ry+9\nrofdL240ju/yWmCLTanpLcNJzgaqOxH9CCMbwM1xg2hkwaqYu8xr1h1hkPsO\n/TtSqoDjOApGSe2vkXjAs/eg8EHlz+W25yStVOGoxQ4pPUyK+dln81ucyLh9\nnWRSsDZElo8h2MB+CPnDkfZvuta8JEMqGerZLxpMjLaw+sTkz5Cx6UoGpLJl\nI/bN6vfm+DAPTponZOQeUJcg1d89RGxGnCM9hhXy+H6JyKjWCSXmVcP9274P\np9avP85F5lSHBUownBkDaQCHWWmkUUlud6kRhY143nlIN+GG6tO7ioZq7f8s\n5UCzNvDcximkdWNTHDG00fHJ8kV3IrVI6Xtl8IOMlBK8YlRnQmSu6KmXAnOZ\nu8P3NSpK76q9OJbgl1J2PIA4naWMRV5Q3OmT7HFZ/vy4wjedSOV42aYbxzP4\nj+sQwsM2zh2B4voOtEY3lx0ZOEs59cBJde2Dt63WgDFjQ0Qpt4oVkk/13vcP\nrUdMSjdKHFoPlIHIIVgTeXt8aYBPhwWngFsrFFMT5cuDGS6itPeA8/52rlnl\nyOSiweR16iFV7Oelgp8h8VXcw0pq1b/ZW4EYS3kZ2KhVmLCzPNSLoE6DELlf\nUc79D7z0j4Ry0iqbC+n118gGsszVjyVuxVdcO8mBERUYrGTb+YMH72aYsvJw\nHo0A\r\n=qIm8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEJ5pUidluclAsSqcc9fWFNhIACollZUKusIZmFzsCEDAiEA6UzyCwiqGlL8VlZJgSk8tnEmnvWTQg2zHXTUi8ZnzcE="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.1.0_1614079897123_0.005926235599486462"},"_hasShrinkwrap":false},"1.1.1":{"name":"@appbuckets/app-router","version":"1.1.1","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/qs":"^6.9.5","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","qs":"^6.9.6","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.1.1","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-YsoWzit/xHb3j/WcoBttH1HOv4N65FzuaV2S14GCFScFVvpusmyrnlCmj0BxyoLSaTcKSSEjGu66Jgqi8wq4yw==","shasum":"168bd697a017068b8ff1162167c92f676332cafc","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.1.1.tgz","fileCount":43,"unpackedSize":234236,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgPkItCRA9TVsSAnZWagAA8ssP/1KLcX7/p3Rth8GnJrZO\nhRjvreUPG49PJ+rvllJb096aC7imCFu+btueDbOQhXSc1GM41DKKPo2dSwIV\nXDZoGuET5lhcQ0TCId40xlhpK/XYi6cTPLErEpCNN6T2oh7U5R9gira155Pe\nqNNQTs/8AUAy544RwmJK4OwmCDSdisNoEWCf7GVrMx7TSeWjPjAQ+LCR5Syk\n2rQCg33e6vWQuLeRcMOQLoFNcJ+OOMV+NUt2li9ISLHenxsMdEnb2rVdFybu\n7c/4gKO+foVSFUun3wmWQK5Nbi2BYQd8WrNb3hjha3vwa+FHR/PeZ/gsgIQz\nNI0h1Gq1BK98hALPbisL6QVlqKDqAsiaNEZpmB8EI8Cfb2RGr1nlNrmgjxyZ\nhf5iHlkgIrTyFg60jsHrCR4nJt69yde6mP3P2hR4+0AARcEriLt74SEQxffq\nzdwpOXcb/BY0MEUlcBXZGgybwWfyldrn2aa8JDeUWxAW/IxAU0FQXUEwHwgh\nLkOYkL0LnylsWGmyh0p5b7A9Xq3qKGE/NGynErxC1qoBvS5r/k2Fnnu3YWmC\n6CBFmkU3PftUzJax6Ljwycz68w2S5hCpipAcARq00YRWezuWwruPmucbJY41\ngZb0xDkaeiuhpNb6eqhiGyLtLT6FXoxi8sDuPMV98XFZ6M88WVFoeRz+ViCQ\n4vrH\r\n=0Tx/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDXeKiEIfNAhmnXXib8KUOalAyrAo/9awhQE9kQ737fygIhAMVpRI+uuHhaT/ZFLjJvhIq6N00LEQKzChx8rKvttL0s"}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.1.1_1614692908627_0.8414661458487893"},"_hasShrinkwrap":false},"1.1.11":{"name":"@appbuckets/app-router","version":"1.1.11","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/qs":"^6.9.5","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","qs":"^6.9.6","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.1.11","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-gJHh+DDSuXS0SEgeIEpoYgKzVXSn+Mv8RUTOPIskx/z6q+pzc3Lj4CxMQZwJFQWM785+foOu/ugPWGV+2XH9zg==","shasum":"719d1cffc94fec4d29f3b7c01dcc71c37c52ed47","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.1.11.tgz","fileCount":43,"unpackedSize":234841,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgPkVjCRA9TVsSAnZWagAAnygP/2Yh+kIzgJ91HyBbo45A\nlf8DpccOVCfamz9m9SHfsBn1zVWPHHy4Ji9BlSalj5JQSuhZhmRUpMYq3Y2D\nPoPgljM2O+SQxOYaST8JSCfYWRVc8E6uOi/x0iFCqpzKWJCJyeRbe1RNcOu2\nT+I7zh+2AYcUeiAtWKQPvesiFTpDbTLTiaBi1Sy2IRJGwCKaT+NP+ffOahev\nY5de/6Km2pBsW6hs+yZdr132rrfJ6mVHKUDr1cjJNBol1YFZW+elKtfz9gly\n8nAqO9XmRwVl3cp/FuY8ShVp6duaTU60pnslTo4NHuUwLUxZRC823CfOy3DJ\nMIUDX/Fr+DpnanCptkuBnvX21mjo9Pxlp/eFuw93itL1e7mlColL/fUvHOVK\nfAeZuMB5Km2tmvYI/jpWO1bySkqXc5IRKZ3viVDBGdW2tKqpsHwCEXGEmJxA\nRGKi3J2QFYuf1YOOI9e5K3eMTI/CY1UhchlWuVeKRRnjMChqp5gPNKbZERQT\njm2PdQtSFlOIeyDeOWsdYnywyuhn7uuHE4awZa/BfeAxoKy+YF/2QhpnRBeI\nttOkH3ljzCcgAtzzd8ITvGIiWHqPkdMEKhDlxj79wu0KtqoEFG7V5vW1e1vJ\nTpa+jrMIUlOpEKsa9zNf5u4I4t3O3knyrOfZ5eO1ohfX0ppZg/F51uNjb6o2\n1Z4D\r\n=eNHr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDwnTx8JFe5NDwM2eCfH5K0P4ls6eYHl/fRidQqfF4YmAiEA/akLo5V4B8dAfxNBSL0S27mtbOvfmsSlB+RNX/yfPBU="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.1.11_1614693730809_0.7581033481518857"},"_hasShrinkwrap":false},"1.1.12":{"name":"@appbuckets/app-router","version":"1.1.12","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/qs":"^6.9.5","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","qs":"^6.9.6","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.1.12","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-iJXg+O8kxWynnGHwBgjn0WfNE3j1kV34W9622oDklEZ55FP89NuQtk6knGYOAxl4/EIbstOlJYQav6LujbI6gQ==","shasum":"c11de42366b24e79816e4e6c51a401263bf7595f","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.1.12.tgz","fileCount":43,"unpackedSize":235031,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgWxNBCRA9TVsSAnZWagAA2fUP/2Veto/OTInVFcb69zw4\nDotnuhlsvb7RbTdw5WuRATpHaKiI7bQclQua+4Hbd7xTwJE+LRgqPnk/IrxG\nWSigV2jFHYChw+HM338fvoquz+CQ96Go+cwSUDgdcyWuuFmBKKZnzhG2au4w\nDIiak2QsF4DefJq3+zGeHs4D3p77/JNZXB80LgIJCCtc2g8aGdayFtfyQbbW\nIUHi/IxCq3PGiVxbsodEscSPQdyFcZSw9HQdPV3ALwS2QEn43obKvWUaonbT\n2obilJC8ZVBTWFC/EzBVTpMuQOklufwtpiKHpvqZMv+kkw0wApyv76y7Cube\nc4QjgBVw1FmXbwqeJiOfERHQaFcqheZekAeH9LMeLEpWP9mENvNA/SyiZfUs\nokEIbZtVx/XBhYSa8INCYQIne/GeEpuJtHzNSFPSdP6YiXgRsbJRhuRIFmIe\ntCnEeGhPnDxy7ybOBvvOOh2D9L7XrzaVFInmC803rl52KqJFINOZL13E3U4d\nW/x4dJblKk4ge7oABY5dG4yNevwatQTiXy0JkPnqsQNNX0VVfb50FGw6QCdx\nm4YeAl15sd6l6sHnUS3yqEneAJH0tGMZlvELGqFd8lO1Z7jHn+MCilMbExqk\nzZgkFY+U9wCdbS5Xx6pNzeXey/b7c8yQT+e305LvYVQK+a/6P8a+yqzOU4Rh\nFnXQ\r\n=DiRb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGV+ALpch8ngtLfNwAljsMA+SgXZrJMyM8lnhfuTYC4jAiBxk/XeN/D+a3OZ8RbX7Ieyt+7vGcyCu/JXtUpiUdagfw=="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.1.12_1616581440981_0.08414539341798766"},"_hasShrinkwrap":false},"1.1.13":{"name":"@appbuckets/app-router","version":"1.1.13","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":"^16.13.1","react-dom":"^16.13.1","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/qs":"^6.9.5","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","qs":"^6.9.6","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.1.13","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-KMZLAjVXRyCHiQEuATVf8AB7VG01hKFANa+syXpJ3n3RgYeIVPxyVO9ETePp7t0dAHgDRztg1+qE8N0ip+4bBQ==","shasum":"e52a6258007ffb844b1b662d337d8c10c9c171ec","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.1.13.tgz","fileCount":43,"unpackedSize":235375,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgbYH9CRA9TVsSAnZWagAAY2oP/ROejxfX2spiCNWvxKN4\nCCAT6RTB8ylrr7dYr/mnflXY6evnm3ulR1sNbH6H5LSgZz97XAZ149rNgD5X\nDUIR7Q/1lXm+rCgOVGnMjpos3vyaO7dOmRm65HOYMK2X/Bi7JU8g2wTr5lJP\nAudl8V5PDcyNukskEvuQ3/glvwYWy00hXn8yeinlBrTwCeOLA9X71u9qmCbx\nqdRC7Xp9s0qu+gd2n/Hx7O4br0tLbT7ZaeKsYCFep3hH6/ltoprBogvoePjD\nrYvzh11JqHSzJavCRIpgprBx5peld58wn2Y1+EPPPcA3Dr6/0syxaY3ef2NE\nCdh/Gjf2i/FqQUuTqyKEhAI2eBMH2Bo6vnXY9j4LEMpDYH3PdPgxwKHog6iu\noxeVMUSiforCouGHBH2kZ0celzgeDjQq0zPrJ245zqU61xbsnQzXTn6JCRiY\nulpRtZ19EGLDX49wZovWWp+xn4zwcWASD83mDsarPMrmciOziI6YoUDxpun1\nBqYQx4EHBovwDbUum5k/uDsBvYa9XEDtBxZhngD7Bb67/7xtnok7gB/vj6RO\nbrpwccM22Y5SoInxnO7rSSpEgrd/OYnmXjdgKf0nHDhdttmB2s0JKaKCAi7/\nT2w2cN+vHmP8Wugb3x0aniG39zCVK/l02qpm0PwRByaXsjr+8unST3TM5GzV\nTSkt\r\n=qIZW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDw/TcYOdsYIWy0p4SVkyHln/OVicRNdKT4jzH7F/HVSQIgR9aqmdk1NEo5FKB5VjJm2sMcs3cjY+n3NSLons56rYI="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.1.13_1617789437377_0.0018215365613674095"},"_hasShrinkwrap":false},"1.1.14":{"name":"@appbuckets/app-router","version":"1.1.14","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":">=16","react-dom":">=16","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/qs":"^6.9.5","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","qs":"^6.9.6","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.1.14","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-rfiffY0BLmS4u7atEt1zQFAFXCiGQNbenY8P0fQzo10s6LI1qk9+GUcteh3HNCzaTG8qAIotYfkHJgB6Xzvg5g==","shasum":"fe470ba820f8785689a999e2bb0b799d1a13b6a9","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.1.14.tgz","fileCount":43,"unpackedSize":235367,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgbkMtCRA9TVsSAnZWagAATzoP/iTVZkVLfjotgvnusbyy\n+WnwfH/YUQAIr8KYFRcetET2xADHwewhJBHtLhZ5yYc8NgK1piXHm/95Ahq0\ne6leu+hkGdVPQZaw7zurH0FxM4ovCvK/4EKWD2ItAHDShouRF9bgVVKk+chn\nMjRMy1yxbJLPwPAJHjvwUtgKwv7yLe/J5NxoHkmxJBcYhlEtUOYlS2dW+uN2\n1784n7AuNj+oqV5/kyi+ysDCDPvs3HGjeKvzJf+KSL6OZjdrmcmEWn0Jumox\niHnMdhCHsrRy2wPYtd6SLmAS2zsKhb4PligItETNGJ2eiQ9kgfKfA3ng4N6t\nVq2kLQemXYmXoe/GFLRCMJ/ZvWlUKF/JpSiBqCsLhyxgyBzlOkaAcOIuHJdM\ndtnrdUGg0Q9I9YtTqt5NRpih/hOw6kCYqUhvCPR3k6NSlQJ0CukS1kwnN5jN\nMWz6/7EJIjxcdi/VhNQ3MJQyx0OMiAmWNbiKfTpngOy/9M08yF6oNAXQNI5I\neb8IMToPo7uT4oML9fGUI7aSA3pPkmzpDPYOObVXXQvom2hYH0mp8f8QmL7R\n3L4Fa/C3B5TOpIox0OqyJz4vBRLeUlFigMD5D4njQvoQqr298lYQrngycH88\nfavoH2grhrnvSDxDrnSFuJLYZg9kUMn1wMLR8nhtQn87f29xzVLwfdEG60Ly\ntF6/\r\n=WE4H\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIApRM6YxpykixexcD1qEh7c3J1NwDcF3LJfuZhcFojo8AiEA8tVvtqsWgMbQSzyYl7ywgwQSxZhS/M0Hs7zlPtPZQt4="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.1.14_1617838893260_0.19467099404104804"},"_hasShrinkwrap":false},"1.1.15":{"name":"@appbuckets/app-router","version":"1.1.15","description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","keywords":["react","router","routing","auth"],"publishConfig":{"access":"public"},"main":"dist/lib/index.js","module":"dist/module/index.js","types":"dist/types/index.d.ts","author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"homepage":"https://github.com/marcocavanna/react-app-router#readme","license":"MIT","scripts":{"prepublishOnly":"npm run build","prebuild":"rimraf dist","build":"rollup -c rollup.config.js","build:prettier":"prettier --config .prettierrc --write \"dist/**/*{.js,.ts}\"","build:declaration":"tsc -p tsconfig.declaration.json","postbuild":"npm run build:declaration && npm run build:prettier"},"peerDependencies":{"react":">=16","react-dom":">=16","react-router-dom":"^5.2.0"},"devDependencies":{"@rollup/plugin-commonjs":"17.0.0","@rollup/plugin-node-resolve":"^11.0.0","@types/node":"^14.0.1","@types/qs":"^6.9.5","@types/react":"^16.9.35","@types/react-dom":"^16.9.8","@types/react-router-dom":"^5.1.5","@types/recompose":"^0.30.7","@typescript-eslint/eslint-plugin":"^4.9.0","@typescript-eslint/parser":"^4.9.0","eslint":"^7.15.0","eslint-config-airbnb-typescript":"^12.0.0","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.4","rollup-plugin-typescript2":"^0.29.0","ts-node":"^8.10.1","typescript":"^3.9.2"},"dependencies":{"clsx":"^1.1.0","qs":"^6.9.6","slugify":"^1.4.0","tiny-invariant":"^1.1.0"},"_id":"@appbuckets/app-router@1.1.15","_nodeVersion":"14.15.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-eFzvnO85gFTQrEktVuSQOUvT7LRJiCjkC3hCNxZuQpHnFC9AJkUQ2e82o0Fx/v1W0SQl0jP51BchEd058v3+iQ==","shasum":"ba650ae55ef50b0b346e024e629a9846d8332e7d","tarball":"https://registry.npmjs.org/@appbuckets/app-router/-/app-router-1.1.15.tgz","fileCount":43,"unpackedSize":235427,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJho9aDCRA9TVsSAnZWagAAWdsQAJI3dRtBO93VGkoIcI7L\nhAE0cjp6gDkmg7kYcGZ01pBcZGRARH1bgrfy+xK/vPvxVakn6aEZ3xQarbS+\neN+ENaL1n/vKQmv4hnNteyMzNe63xVAWjMAWqO5ovfJ6L6AmJd+FlzVRFJEa\nmou/jvcwOkHfx8/+HUqRbfm5aOhxxwnqAgSkYqSS0GhtqzKSWHSImha4DUOf\nyl1cZxjsN4C4OaPKoQxY8xatDKfmXX02UEons34sK+e/WlDcCnbXuczWxVmP\n9SHzOyoHKYp6F2+nk8uYXDEOZ41H4aToEuiBk1MBDU6EKkk03p2rwFi0zVoD\nlK0bFFokjlMS5XrM77PhGBM0nYGUx9wKsJRcVNWYzLoXfQbHgGhObIdmewVG\n6urcPrdbaJO5nuyfuKm09K3BrRQYbCWxtBerach8gGclbsXtQd+xqHulImJt\nSWujKG1iabq81h4DJVCEEl/W6x5oXdni2FCWd/tGKkOgo3/vf27yHKdsBOmh\nBy3oj4YKIJss5/xHh7hmJS9f+vEbi/Y6SC2OZfZtYuActjGFR3sXc8Sz5Yfw\nz5A8+fcEC54pgNmQYdT2V6EWANFTDzgBmEPCuOa/pU/5PMKY8kYwi4Cpm5P0\nj/9bUu5lis2fpsFhOoZEyOTZi+GrJqYWTp7NUzC7OHhIOE1ZjWb7ox+4aRHb\nbGZL\r\n=vAmY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDvPnPc8HjZdrt3ova26Hx7A9uyoplNjPBZnshVZ2z21QIgEYBpg+Uybr5o/jTUkAwpbeSD4UJETVo/KhPfD3QeppQ="}]},"_npmUser":{"name":"marcocavanna","email":"marco@appbuckets.io"},"directories":{},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/app-router_1.1.15_1638127235075_0.333683997154663"},"_hasShrinkwrap":false}},"maintainers":[{"name":"marcocavanna","email":"marco@appbuckets.io"}],"description":"An AppState and AppRoute wrapper of react-router-dom with AuthState","homepage":"https://github.com/marcocavanna/react-app-router#readme","keywords":["react","router","routing","auth"],"repository":{"type":"git","url":"git+https://github.com/marcocavanna/react-app-router.git"},"author":{"name":"Marco Cavanna","email":"marco@appbuckets.io"},"bugs":{"url":"https://github.com/marcocavanna/react-app-router/issues"},"license":"MIT","readme":"[![Contributors][contributors-shield]][contributors-url]\n[![License][license-shield]](#)\n[![Size][size-shield]](#)\n[![Download][download-shield]](#)\n\n<br />\n<p align=\"center\">\n  <h2 align=\"center\">React AppRouter</h2>\n\n  <p align=\"center\">\n    React RouterDOM Wrapped\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router\"><strong>Explore the docs »</strong></a>\n    <br />\n    <br />\n    <a href=\"https://github.com/marcocavanna/react-app-router/tree/master/example\">View Demo</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Report Bug</a>\n    ·\n    <a href=\"https://github.com/marcocavanna/react-app-router/issues\">Request Feature</a>\n  </p>\n</p>\n\nThe React AppRouter module is a series of components built on top of [react-router-dom] library.\n\nI've written this library to easy manage routing for auth based app, enforcing route by checking the user auth state and easily manage loading state while performing actions (like loading the client, the initial user data before app start, and so on).\n\nThis library could also easily manage sidebar/navbar presence on each route, defining a global Sidebar/Navbar elements on AppRoute.\n\nComponents are written purely in TypeScript trying to be strongly typed: refer to [TypeScript Usage](#typescript-usage)\n\n\n## Core Concept\nReact [AppRouter](#approuter-) is based on an array of [`AppRoute`](#approute) object elements, injected by the `routes` props that is mandatory. Each route must contain:\n\n- a unique `name` string key\n- the `path` string (same as `<Route />` element in react-router-dom, except as an array of string, because it is not supported yet)\n- the `component` key, that is the page component used to render the page\n\nUsing the [`AppRoute`](#approute) array, the AppRouter component will create each single `<Route />` and some other useful utilities.\n\nThe strength of this module is that in you page you could refer to route using its name, and not its path.\n\nFor example, if you ar writing a blog, you'll have a single article page. On traditional system you'll refer to this page using:\n```javascript\n/**\n * Suppose you have declared somewhere into your app the BrowserRouter\n * end each single routes. One of this route points to a SingleArticle\n * component and is composed by some params\n */\n<Route component={SingleArticle} path={'/blog/articles/:category/:slug'} />\n\n/** Refer to this path in you app will be a little verbose */\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <Link to={`/blog/articles/${category}/${slug}`}>{title}</Link>\n))}\n\n// or, in a component function you could use react-router-dom hooks\nconst history = useHistory();\nhistory.push(`/blog/articles/${category}/${slug}`);\n\n\n/**\n * With AppRouter module you could declare your routing using an array\n * of Route, with a unique name, and you could refer to that name\n * to push new location\n */\n\n// eg. looping articles array to build link\n{articles.map(({ category, slug, title }) => (\n  <AppLink to={'Article'} params={{ category, slug }}>{title}</AppLink>\n))}\n\n// or in a component function you could use 'app-router' hooks\nconst { routeTo } = useRouting();\nrouteTo('Article', { slug, category });\n```\n\n\n## Getting Started\n\n### Installing\nYou can install React AppRouter using Yarn:\n\n```\nyarn add @appbuckets/app-router\n```\n\nor using npm\n\n```\nnpm install --save @appbuckets/app-router\n```\n\n\n### Base Examples\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { useParams } from 'react-router-dom';\n\nimport { AppRouter, AppLink, usePageTitle } from '@appbuckets/app-router';\n\n// Define the Home Page Component\nconst Home = () => (\n  <React.Fragment>\n    <h1>Welcome to Home Page</h1>\n    <h3>This page is visible only to User without Auth</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Read Some Articles</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define the Article Page Component\nconst Articles = () => (\n  <React.Fragment>\n    <h1>Choose an Article to Read</h1>\n    <h3>This is an Hybrid page, visible to both authorized and unauthorized Users</h3>\n    <hr />\n    <div>\n      <h4>Here are some Articles to Read</h4>\n      {[ 1, 2, 3 ].map(id => (\n        <AppLink key={id} to={'ShowArticle'} params={{ id }}>\n          <h5>Go to Article number {id}</h5>\n        </AppLink>\n      ))}\n    </div>\n    <hr />\n    <AppLink to={'Home'}>\n      <h3>Return to Home Page</h3>\n    </AppLink>\n    <AppLink to={'UserProfile'}>\n      <h3>Go to your personal Profile Page, link visible to Authenticate User Only</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define a Page to View a Single Article\nconst ShowArticle = () => {\n  // You could use same react-router-dom hooks\n  const { id } = useParams();\n  // You could use extra hooks defined in app-router\n  const [ currentPageTitle , setPageTitle ] = usePageTitle();\n  // For example to set the page title\n  setPageTitle(`Reading Article ${id}`);\n\n  return (\n    <React.Fragment>\n      <h1>{id} Article Titles</h1>\n      <h3>Articles Subtitles</h3>\n      <hr />\n      <AppLink to={'Articles'}>\n        <h3>Return to Articles List</h3>\n      </AppLink>\n    </React.Fragment>\n  );\n};\n\n// Define the Personal Profile Page\nconst Profile = () => (\n  <React.Fragment>\n    <h1>Your Profile</h1>\n    <h3>This page is visible only to authenticated User</h3>\n    <hr />\n    <AppLink to={'Articles'}>\n      <h3>Return to Articles List</h3>\n    </AppLink>\n  </React.Fragment>\n);\n\n// Define Routes\nconst routes = [\n  {\n    name     : 'Home',\n    path     : '/',\n    component: Home,\n    title    : 'Home',\n    isPublic : true\n  },\n  {\n    name     : 'Articles',\n    path     : '/articles',\n    component: Articles,\n    title    : 'Articles List',\n    isPrivate: true,\n    isPublic : true,\n    isDefault: 'private' as 'private'\n  },\n  {\n    name     : 'ShowArticle',\n    path     : '/articles/:id',\n    component: ShowArticle,\n    title    : 'Single Articles',\n    isPrivate: true,\n    isPublic : true\n  },\n  {\n    name     : 'UserProfile',\n    path     : '/profile',\n    component: Profile,\n    title    : 'Profile Settings',\n    isPrivate: true\n  }\n];\n\n// Create the App\nconst App = () => {\n\n  const [ hasAuth, setHasAuth ] = React.useState(false);\n\n  const handleToggleAuth = () => {\n    setHasAuth(!hasAuth);\n  };\n\n  return (\n    <AppRouter\n      defaultAppName={'Routing Example'}\n      userHasAuth={hasAuth}\n      routes={routes}\n      components={{\n        Footer: () => (\n          <React.Fragment>\n            <hr />\n            <p>I am a Static Footer Component, showed on Each Page</p>\n            <button onClick={handleToggleAuth}>\n              {hasAuth ? 'Remove User Authorization' : 'Authorize User'}\n            </button>\n          </React.Fragment>\n        )\n      }}\n    />\n  );\n};\n\n// Render\nReactDOM.render(\n  <App />,\n  document.getElementById('root-app')\n);\n```\n\n<br />\n\n---\n\n## Usage\n### Components\nReact AppRouter consists in 1 core components (the [`<AppRouter />`](#approuter-)), and some side useful components (like [`<AppLink />`](#applink-)).\n\n#### `<AppRouter />`\nThe __AppRouter__ is the mandatory component to let the React AppRouter module work. It wraps, under the hoods the original [`<BrowserRouter />`](https://reacttraining.com/react-router/web/api/BrowserRouter) component from [react-router-dom].\n\nComplete `props` description are defined in [`AppRouterProps`](#approuterprops) interface.\n\nSome principal AppRouter props are:\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `defaultAppName?` : `string`\n> Page title will be defined every time user route to a new page.\n>\n> Each route has is own title, but if you want you can provide a default AppTitle that will be prepended to single page title.\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n---\n\n#### `<AppLink />`\n__AppLink__ component is a wrapper for [Link](https://reacttraining.com/react-router/web/api/Link) or [NavLink](https://reacttraining.com/react-router/web/api/NavLink) elements of [react-router-dom] library.\n\nAdditionally, the Link elements will be rendered only if current user could reach that route, based on [`userHasAuth`](#userhasauth--boolean) state of parent AppRouter.\n\nAppLink extends all props defined in Link or NavLink element, except for the `to` props that must refer to valid AppRoute.\n\nRefer to [`AppLinkProps`](#applinkprops) interface.\n\n<br />\n\n---\n\n### Hooks\nHooks are used to manage routing, or get route state on function components.\n\n#### `useAppState()` : [`AppState`](#appstate)\n> Get current app state\n\n#### `useLayout()` : [`AppRouterLayout`](#approuterlayout)\n> Get the layout state for current route. This hook is used internally by PageWrapper, but exposed anyway for further usage.\n\n#### `useAppName()` : `[string, changeName: ((newName?: string) => void), restoreDefault: () => void]`\n> Return a set of three elements:\n>   - The current name of the App\n>   - A function to set a new name\n>   - A function to restore the name declared in [`defaultAppName`](#defaultappname--string) props of <AppRouter /> component\n\n#### `useCurrentRoute()` : [`CurrentRoute`](#currentroute)\n> Returns an object that describe the current routes, composed by:\n>   - `route` : [`AppRoute`](#approute) The current route object\n>   - `params` : `{}` Current params of route\n>   - `search` : `URLSearchParams` Search query string converted to [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n\n#### `useRouting()` : `UseRoutingTools`\n> Returns an object that contains useful route methods and properties:\n>   - `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void` Route to a path\n>   - `couldRouteTo` : `(route: string | AppRoute) => boolean` Check if a routing to `route` could be performed based on `userHasAuth`\n>   - `getRoute` : `(name: string) => AppRoute | undefined` Get a Route Object by name\n>   - `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void` Route to the default private route\n>   - `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void` Route to the default public route\n>   - `defaultPrivateRoute` : [`AppRoute`](#approute) The default private route object\n>   - `defaultPublicRoute` : [`AppRoute`](#approute) The default public route object\n\n#### `usePageTitle()` : `[string, changeTitle: ((newTitle?: string) => void)]`\n> Return a set of two elements:\n>   - The current page title\n>   - A function to set a new page title\n\n<br />\n\n---\n\n### HOC\nAn only High Order Component is provided\n\n#### `withAppRouter`\nWrapping a component with this HOC will produce a new component with `appRouter` props. Refer to [`AppRouterTools`](#approutertools) to check how its composed.\n\n<br />\n\n---\n\n### Interfaces\nInterface describe below use the TypeScript syntax. A `props` or an `option` marked by `?` char is considered as optional.\n\n\n#### `AppRouterProps`\n##### `appendRouteClassNameTo?` : `HTMLElement`\n> Set manually the HTML Node where route classname are appended, falling back to `<body>` element.\n>\n> When a location changed event, current route will be splitted into route tree and appended as className\n> to the element defined into `appendRouteClassNameTo`. For example, if your current route is '/blog/article/tech',\n> 'blog', 'article' and 'tech' string will be used as className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> ClassName will be transformed using `slugify` module\n>\n> Additionally, also the current hash will be used as className\n\n##### `browserRouterProps?` : [`BrowserRouterProps`](https://reacttraining.com/react-router/web/api/BrowserRouter)\n> Props passed to the wrapped `<BrowserRouter />` component.\n\n##### `components?` : [`SideRouteComponents`](#sideroutecomponents)\n> A set of component rendered outside the wrapped page, like Sidebar, Navbar, Loader, ecc..\n>\n> Refer to linked interface to get each props.\n\n##### `defaultAppName?` : `string`\n> Set the current AppName. This text will be used to create the App Title on each Page.\n\n##### `fireOnRouteChangeEventOnMount?` : `boolean`\n> Choose if must fire the `onRouteChange` event handler on AppRouter mount.\n>\n> By default, this props is `true`\n\n##### `hashClassNamePrefix?` : `string`\n> This string will pe prepended to current hash while setting the hash className.\n>\n> This option will be considered only with `useRouteClassName`\n>\n> By default, this props is `hash-`\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isInitiallyLoading` equal to true\n> \n> By default, this props is `true`\n\n##### `hidePageWhileLoading?` : `boolean`\n> Set if the Page Component must be hide while app state has `isLoading` equal to true\n> \n> By default, this props is `false`\n\n##### `isInitiallyLoading?` : `boolean`\n> App State could be set to isInitiallyLoading to prevent page render while the App is starting.\n>\n> This is intended to show for example a full page loader on App Initialization.\n\n##### `isLoading?` : `boolean`\n> App State could be set to isLoading any time, to show a loader component while performing some long/system functions.\n> \n> This is intended to show for example a different loader while performing Login/Logout Operation.\n\n##### `innerClassNames?` : `{ pageClassNames?: ClassValue | ClassValue[], viewClassNames?: ClassValue | ClassValue[] }`\n> Page Component will be wrapped by an outer <div class='view-content'>,\n> that contain all route elements (sidebar, header ...), and an inner <div class='page-content'> that wrap your page.\n>\n> If you want you can add any class to wrappers. Additional ClassName are merged together using `clsx` library.\n> Refer to [clsx] documentation to know what `ClassValue` is.\n\n##### `getNextRoute?` : `(props: AppRoute, appState: AppState, routeProps: RouteComponentProps) => string | null | MandatoryRedirect`\n> This function will be called after a location event occurred, but before the page rendering function.\n>\n> Use this function if you want to mandatory redirect a user to another page. You could return a string to refer directly\n> to a defined route, or an object (described on [`MandatoryRedirect`](#mandatoryredirect)), with route, params and state.\n\n##### `hasNavbar?` : `boolean`\n> Set if AppRouter must render the `Navbar` component on page where Navbar has been enabled\n\n##### `hasSidebar?` : `boolean`\n> Set if AppRouter must render the `Sidebar` component on page where Sidebar has been enabled\n\n##### `onHashChange?` : `(current: string, location: Location, history: History) => void`\n> A handler callback invoked each time hash changed.\n\n##### `onRouteChange?` : `(current: AppRoute, location: Location, history: History) => void`\n> A handler callback invoked each time location changed.\n\n##### `routes` : [`AppRoute[]`](#approute)\n> Define each single route. Check the AppRoute interface to get documentation on each prop to build your routing system.\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Set the Page Title used while app is in Initially Loading State\n\n##### `pageTitleWhileLoading?` : `string`\n> Set the Page Title used while app is in Loading State\n\n##### `pageTitleSeparator?` : `string`\n> Set the Page Title separator.\n> \n> When the title inside <head> will change, computing function will use the current appName string,\n> and the current page title string: set this props to choose how the two names will be joined together.\n\n##### `userHasAuth?` : `boolean`\n> Tell the AppRouter if current user has authorization to show a private page.\n>\n> Changing `userHasAuth` on private/public only page will automatically perform a mandatory redirect to default private/public page based on user auth.\n\n##### `useRouteClassName?` : `boolean`\n> Tell the AppRouter must append current route className to HTMLElement defined in `appendRouteClassNameTo`\n\n---\n\n#### `AppRoute`\nAppRoute interface is used to describe each single Route.\n\n##### `component` : `React.ComponentType<RouteComponentProps>`\n> Is the component used to render the page at current route\n\n##### `exact?` : `boolean`\n> Set if this route must be reached only if exact path has been typed by user.\n>\n> By default, value is `true`\n\n##### `hasNavbar?` : `boolean`\n> Set the page has the Navbar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `hasSidebar?` : `boolean`\n> Set the page has the Sidebar component visible\n>\n> By default, value is `true` if route has `isPrivate` set to true\n\n##### `isDefault?` : `boolean | 'private' | 'public'`\n> When the App start, or when `userHasAuth` prop changed, if current page\n> could not be reached by user, routing will fallback to default page\n> based on current `userHasAuth` prop.\n>\n> For a hybrid page (when a page is both public and private) you could\n> manually set if current route is default for private or public routing\n\n##### `isPrivate?` : `boolean`\n> Set if the page is Private.\n> A Private page could be reached only when `userHasAuth` is true.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `isPublic?` : `boolean`\n> Set if the page is Public.\n> A Public page could be reached only when `userHasAuth` is false.\n> You could declare a page both private and public:\n> the result is a Hybrid page, visible by user with and without auth\n>\n> Default is `false`\n\n##### `name` : `string`\n> The unique page name\n\n##### `path` : `string`\n> The page path\n>\n> Alert: `react-router-dom` will accept also an array of string. At the moment this is not accepted by AppRouter.\n\n##### `sensitive?` : `boolean`\n> When true, will match if the path is case sensitive.\n\n##### `strict?` : `boolean`\n> When true, a path that has a trailing slash will only match a location.pathname with a trailing slash.\n> This has no effect when there are additional URL segments in the location.pathname.\n\n##### `title?` : `string`\n> The page title, appended to current AppName\n\n---\n\n#### `CurrentRoute`\n##### `route` : [`Readonly<AppRoute>`](#approute)\n> The current Route object\n\n##### `params` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to reach current rout\n\n##### `search` : [`URLSearchParams`](#https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)\n> Converted search query string to URLSearchParams object\n\n---\n\n#### `AppState`\nThe current state of App, represented by\n\n- `isInitiallyLoading` : `boolean`\n> Get if app is in Initially Loading State\n\n- `isLoading` : `boolean`\n> Get if app is in Loading State\n\n- `userHasAuth` : `boolean`\n> Get if current user has auth\n\n---\n\n#### `SideRouteComponents`\nA set of components used to render the whole app page.\n\nEach declared component receive as props the `appState` key, an object containing the current state of the app.\nRefer to [`AppState`](#appstate) interface to props description.\n\n##### `Footer?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered under the Page\n\n##### `Header?` : `React.ComponentType<{ appState: AppState }>`\n> A content rendered above the Page, but under the Navbar (if present)\n\n##### `InitialLoader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isInitiallyLoading` equal to true\n\n##### `Loader?` : `React.ComponentType<{ appState: AppState }>`\n> The component to render while app state has `isLoading` equal to true\n\n##### `Navbar?` : `React.ComponentType<{ appState: AppState }>`\n> The Navbar element, rendered on top of page.\n> Setting the Navbar component will not automatically show the Navbar element\n> until [`hasNavbar`](#hasnavbar--boolean) of AppRouter component is true.\n\n##### `NotFound?` : `React.ComponentType<{ appState: AppState }>`\n> Custom component page to show on NotFound page\n\n##### `Sidebar?` : `React.ComponentType<{ appState: AppState }>`\n> The Sidebar element, rendered on left side of page.\n> Setting the Sidebar component will not automatically show the Sidebar element\n> until [`hasSidebar`](#hassidebar--boolean) of AppRouter component is true.\n\n---\n\n#### `MandatoryRedirect`\nThis is an Object that could be returned by [`getNextRout()`](#getnextroute--props-approute-appstate-appstate-routeprops-routecomponentprops--string--null--mandatoryredirect) method to force routing to another page.\n\n##### `route` : `string | AppRoute`\n> The new route\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params used to build the route\n\n##### `state?` : `LocationState`\n> Location state passed to route\n\n---\n\n#### `AppLinkProps`\n__AppLink__ element extends each props of Link or NavLink element plus:\n\n##### `asNavLink?` : `boolean`\n> Render the element as a `<NavLink />` instead as a `<Link />`\n\n##### `params?` : `{ [key: string]: string | number | boolean | undefined }`\n> Params passed to build the complete route\n\n##### `renderAnyway?` : `boolean`\n> By default, a AppLink will be rendered only if current user could reach the requested route.\n> Eg. If a user has no auth, a link to a private route will not be rendered.\n>\n> Set this props to `true` if link must be rendered anyway\n\n##### `to` : `string`\n> The Route Name to point\n\n---\n\n#### `AppRouterTools`\n##### `appName?` : `string`\n> Get the current AppName\n\n##### `appState` : [`Readonly<AppState>`](#appstate)\n> Get the current AppState\n\n##### `currentRoute` : [`Readonly<CurrentRoute>`](#currentroute)\n> Get the current Route and its params and search string\n\n##### `defaultPrivateRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default private defined route\n\n##### `defaultPublicRoute` : [`Readonly<AppRoute>`](#approute)\n> Get the default public defined route\n\n##### `layout` : [`Readonly<AppRouterLayout>`](#approuterlayout)\n> Get current layout settings\n\n##### `restoreAppName` : `() => void`\n> Restore the default app name defined in <AppRouter />\n\n##### `couldRouteTo` : `(route?: AppRoute) => void`\n> Check if a route could be performed to a page\n\n##### `routeTo` : `(route: string | AppRoute, params?: {}, state?: LocationState) => void`\n> Route to a page by name\n\n##### `routeToDefaultPrivate` : `(params?: {}, state?: LocationState) => void`\n> Route to default private page\n\n##### `routeToDefaultPublic` : `(params?: {}, state?: LocationState) => void`\n> Route to default public page\n\n##### `setAppName` : `(nextAppName?: string | ((currentAppName?: string)) => string | undefined) => void`\n> Set a new App Name\n\n##### `setPageTitle` : `(pageTitle?: string) => void`\n> Set a new page Title\n\n---\n\n#### `AppRouterLayout`\n##### `hasNavbar?` : `boolean`\n> Check if current route has navbar visible\n\n##### `hasSidebar?` : `boolean`\n> Check if current route has sidebar visible\n\n##### `hidePageWhileInitiallyLoading?` : `boolean`\n> Check if current page must be hide if app is in initially loading state\n\n##### `hidePageWhileLoading?` : `boolean`\n> Check if current page must be hide if app is in loading state\n\n##### `pageTitleWhileInitiallyLoading?` : `string`\n> Get the page title to set while app is in initially loading state\n\n##### `pageTitleWhileLoading?` : `string`\n> Get the page title to set while app is in loading state\n\n\n<br />\n\n---\n\n## TypeScript Usage\n\n> - [ ] : TODO\n\n## Roadmap\nSee the [open issues](https://github.com/marcocavanna/react-app-router/issues) for a list of proposed features (and known issues).\n\n### ToDo\n- [ ] SubRouting\n- [ ] Define Route in a more declarative way\n- [ ] TypeScript extended functionality\n- [ ] Style base example\n- [ ] More Examples\n\n\n## Contributing\nPlease read [CONTRIBUTING.md] for details on our code of conduct, and the process for submitting pull requests to us.\n\n\n### Fork Example\nTo fix or add new features feel free to fork this repo by:\n1. Fork it ([https://github.com/marcocavanna/react-app-router/fork])\n2. Clone the project on your workspace (`git clone https://github.com/marcocavanna/react-app-router.git`)\n3. Inside the clone repository, add the upstream to this repo (`git remote add upstream https://github.com/marcocavanna/react-app-router.git`)\n4. Create your feature / fix branch (`git checkout -b feature/my-new-route-component`)\n5. Do some cool stuff\n6. Commit your changes (`git commit -am 'feat(component): added a wonderful component'`)\n7. Push your work (`git push -u origin feature/my-new-route-component`)\n8. Create the pull request, from your forked github repository page\n\n\n## Authors\n- __Marco Cavanna__ - _Initial Work_\n\n\n## Built With\n- [React] A library to create UI\n- [react-router-dom] Declarative routing for React\n- [clsx] ClassName Utility\n- [slugify] Create slug from string\n- [tiny-invariant] A tiny invariant alternative\n\n\n## License\nThis project is licensed under the MIT License\n\n\n[React]: https://it.reactjs.org\n[react-router-dom]: https://github.com/ReactTraining/react-router\n[clsx]: https://github.com/lukeed/clsx#readme\n[slugify]: https://github.com/simov/slugify\n[tiny-invariant]: https://github.com/alexreardon/tiny-invariant\n[CONTRIBUTING.md]: https://github.com/marcocavanna/react-app-router/blob/master/CONTRIBUTING.md\n\n[contributors-shield]: https://img.shields.io/github/contributors/marcocavanna/react-app-router\n[contributors-url]: https://github.com/marcocavanna/react-app-router/graphs/contributors\n\n[license-shield]: https://img.shields.io/github/license/marcocavanna/react-app-router\n[size-shield]: https://img.shields.io/bundlephobia/min/@appbuckets/app-router\n[download-shield]: https://img.shields.io/npm/dw/@appbuckets/app-router\n","readmeFilename":"README.md"}