From 3adc9609030a71db65e3c0358018eddd3e14b7f7 Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Mon, 10 Jul 2023 11:33:36 -0700 Subject: [PATCH 01/13] refactor routing to remove hash --- src/App.jsx | 8 ++--- src/AppRoutes.jsx | 34 +++++--------------- src/components/NavBar/NavbarLinks.jsx | 2 +- src/components/NavBar/OidcLoginComponent.jsx | 11 ++++--- src/hooks/index.js | 3 +- src/hooks/useRedirectUrl.js | 28 ---------------- vite.config.js | 1 - 7 files changed, 20 insertions(+), 67 deletions(-) delete mode 100644 src/hooks/useRedirectUrl.js diff --git a/src/App.jsx b/src/App.jsx index bb5a3c4dc..3e5edd5c6 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ // React Imports import React from 'react'; -import { HashRouter as Router } from 'react-router-dom'; +import { BrowserRouter } from 'react-router-dom'; // Inrupt Library Imports import { SessionProvider } from '@inrupt/solid-ui-react'; // Material UI Imports @@ -24,8 +24,9 @@ import AppRoutes from './AppRoutes'; */ const App = () => ( - - + @@ -35,7 +36,6 @@ const App = () => ( - ); export default App; diff --git a/src/AppRoutes.jsx b/src/AppRoutes.jsx index b6f990eb0..3bd9a095a 100644 --- a/src/AppRoutes.jsx +++ b/src/AppRoutes.jsx @@ -1,15 +1,13 @@ // React Imports -import React, { useState, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { Routes, Route, Navigate, Outlet } from 'react-router-dom'; // Inrupt Imports import { useSession } from '@inrupt/solid-ui-react'; -// Custom Hook Imports -import { useRedirectUrl } from './hooks'; // Page Imports import { Home, Clients, Messages, Documents, Profile } from './routes'; const ProtectedRoute = ({ isLoggedIn, children }) => - isLoggedIn ? children ?? : ; + isLoggedIn ? children ?? : ; /** * The main application routing for PASS @@ -20,24 +18,8 @@ const ProtectedRoute = ({ isLoggedIn, children }) => const AppRoutes = () => { const { session } = useSession(); - const redirectUrl = useRedirectUrl(); - const [restore, setRestore] = useState(false); const restorePath = localStorage.getItem('restorePath'); - const path = restorePath ?? '/PASS/clients'; - - useEffect(() => { - const performanceEntries = window.performance.getEntriesByType('navigation'); - if (performanceEntries[0].type === 'reload' && performanceEntries.length === 1) { - setRestore(true); - } - - if (restore && localStorage.getItem('loggedIn')) { - session.login({ - oidcIssuer: localStorage.getItem('oidcIssuer'), - redirectUrl - }); - } - }, [restore]); + const path = restorePath ?? '/clients'; useEffect(() => { if (session.info.isLoggedIn) localStorage.setItem('loggedIn', true); @@ -47,14 +29,14 @@ const AppRoutes = () => { : } /> }> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> } /> diff --git a/src/components/NavBar/NavbarLinks.jsx b/src/components/NavBar/NavbarLinks.jsx index a27bf2758..73e7681f2 100644 --- a/src/components/NavBar/NavbarLinks.jsx +++ b/src/components/NavBar/NavbarLinks.jsx @@ -23,7 +23,7 @@ const NavbarLinks = () => { const theme = useTheme(); // Tabs workaround to match route on login - let location = useLocation().pathname.slice(6); + let location = useLocation().pathname.split('/')[1]; if (location === '') { location = 'clients'; } diff --git a/src/components/NavBar/OidcLoginComponent.jsx b/src/components/NavBar/OidcLoginComponent.jsx index 622119037..cee79f793 100644 --- a/src/components/NavBar/OidcLoginComponent.jsx +++ b/src/components/NavBar/OidcLoginComponent.jsx @@ -4,14 +4,12 @@ import React, { useState } from 'react'; import { LoginButton } from '@inrupt/solid-ui-react'; // Material UI Imports import { TextField, Box, Button } from '@mui/material'; -// Custom Hook Imports -import { useRedirectUrl } from '../../hooks'; // Constants Imports import { ENV } from '../../constants'; const OidcLoginComponent = () => { - const [oidcIssuer, setOidcIssuer] = useState(ENV.VITE_SOLID_IDENTITY_PROVIDER); - const redirectUrl = useRedirectUrl(); + const defaultOidc = ENV.VITE_SOLID_IDENTITY_PROVIDER || '' + const [oidcIssuer, setOidcIssuer] = useState(defaultOidc); return ( <> @@ -32,7 +30,10 @@ const OidcLoginComponent = () => { }} /> - + - - {/* modal/popup renders when showConfirmationModal state is true */} - - + + + + + {/* modal/popup renders when showConfirmationModal state is true */} + + ); }; diff --git a/src/pages/Documents.jsx b/src/pages/Documents.jsx index 824e07fff..897e9ba7f 100644 --- a/src/pages/Documents.jsx +++ b/src/pages/Documents.jsx @@ -23,45 +23,44 @@ import Layout from '../layouts/Layout'; * @returns {React.JSX.Element} The Documents Page */ const Documents = () => { - localStorage.setItem('restorePath', 'PASS/documents'); const { selectedUser, setSelectedUser } = useContext(SelectedUserContext); const { podUrl } = useContext(SignedInUserContext); return ( - - - - {podUrl === selectedUser.podUrl ? ( - Personal Pod - ) : ( - Client selected: {selectedUser.person || selectedUser.podUrl} - )} + + {podUrl === selectedUser.podUrl ? ( + Personal Pod + ) : ( + Client selected: {selectedUser.person || selectedUser.podUrl} + )} - - - - - + + + + + ); }; diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 8f5041be7..ab4bd252c 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -15,26 +15,26 @@ import Layout from '../layouts/Layout'; * @returns {React.ReactElement} The home page */ const Home = () => ( - - - - -
-

HOME PAGE

-
-
-
-
+ + + + +
+

HOME PAGE

+
+
+
+
); diff --git a/src/pages/Messages.jsx b/src/pages/Messages.jsx index b8d522b2c..a5e4358d1 100644 --- a/src/pages/Messages.jsx +++ b/src/pages/Messages.jsx @@ -27,7 +27,6 @@ const routesArray = [{ label: 'Inbox' }, { label: 'Outbox' }]; * @returns {React.JSX.Element} The Messages Page */ const Messages = () => { - localStorage.setItem('restorePath', '/PASS/messages'); const { podUrl } = useContext(SignedInUserContext); @@ -73,32 +72,32 @@ const Messages = () => { return ( - - - - - {routesArray.map((item) => ( - setBoxType(item.label.toLowerCase())} - /> - ))} - - + + + + + {routesArray.map((item) => ( + setBoxType(item.label.toLowerCase())} + /> + ))} + + - - {showForm && setShowForm(!showForm)} />} - + + {showForm && setShowForm(!showForm)} />} + ); }; diff --git a/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap b/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap index 98065439b..c94836303 100644 --- a/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap +++ b/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap @@ -34,6 +34,7 @@ exports[`renders correctly 1`] = ` />
https://www.testurl.com/ + http://localhost:3000/PASS/ +
+ + + +
+
+
+
+

+ HOME PAGE +

+
+
+
+
+ + + +`; diff --git a/test/routes/__snapshots__/Home.test.jsx.snap b/test/routes/__snapshots__/Home.test.jsx.snap deleted file mode 100644 index 8e3d49176..000000000 --- a/test/routes/__snapshots__/Home.test.jsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Home Page > renders 1`] = ` -
-
-
-
-
-

- HOME PAGE -

-
-
-
-
-
-`; From 61fccd7595e28709b97278315d93b962b5ccb77d Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Tue, 27 Jun 2023 09:59:55 -0700 Subject: [PATCH 05/13] Update layouts, fix tabs --- src/App.jsx | 5 +- src/AppRoutes.jsx | 4 +- src/components/NavBar/NavbarLinks.jsx | 6 +- src/components/NavBar/OidcLoginComponent.jsx | 2 +- src/pages/Clients.jsx | 37 ++- src/pages/Documents.jsx | 63 ++-- src/pages/Home.jsx | 41 ++- src/pages/Messages.jsx | 55 ++-- .../OidcLoginComponent.test.jsx.snap | 4 +- test/pages/__snapshots__/Home.test.jsx.snap | 279 +----------------- vite.config.js | 2 +- 11 files changed, 117 insertions(+), 381 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 273b9896e..975dc7ed0 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -12,6 +12,7 @@ import UserDataContextProvider from './contexts/UserDataContext'; import theme from './theme'; // Route Imports import AppRoutes from './AppRoutes'; +import Layout from './layouts/Layout'; /** * @typedef {import("./typedefs").userListObject} userListObject @@ -27,7 +28,9 @@ const App = () => ( - + + + diff --git a/src/AppRoutes.jsx b/src/AppRoutes.jsx index 77c904e0a..4656d33ca 100644 --- a/src/AppRoutes.jsx +++ b/src/AppRoutes.jsx @@ -7,7 +7,7 @@ import { useSession } from '@inrupt/solid-ui-react'; import { Home, Clients, Messages, Documents, Profile } from './pages'; const ProtectedRoute = ({ isLoggedIn, children }) => - isLoggedIn ? children ?? : ; + isLoggedIn ? children ?? : ; /** * The main application routing for PASS @@ -25,7 +25,7 @@ const AppRoutes = () => { : } /> }> diff --git a/src/components/NavBar/NavbarLinks.jsx b/src/components/NavBar/NavbarLinks.jsx index 73e7681f2..d7414436a 100644 --- a/src/components/NavBar/NavbarLinks.jsx +++ b/src/components/NavBar/NavbarLinks.jsx @@ -30,9 +30,9 @@ const NavbarLinks = () => { // array of current nav links for menus const routesArray = [ - { label: 'Clients', path: '/PASS/clients' }, - { label: 'Documents', path: '/PASS/documents' }, - { label: 'Messages', path: '/PASS/messages' } + { label: 'Clients', path: 'clients' }, + { label: 'Documents', path: 'documents' }, + { label: 'Messages', path: 'messages' } ]; // Navigate To... button and menu (small screens) diff --git a/src/components/NavBar/OidcLoginComponent.jsx b/src/components/NavBar/OidcLoginComponent.jsx index 07aaca004..cff307985 100644 --- a/src/components/NavBar/OidcLoginComponent.jsx +++ b/src/components/NavBar/OidcLoginComponent.jsx @@ -30,7 +30,7 @@ const OidcLoginComponent = () => { }} /> - + - - {/* modal/popup renders when showConfirmationModal state is true */} - - -
+ + + + {/* modal/popup renders when showConfirmationModal state is true */} + + ); }; diff --git a/src/pages/Documents.jsx b/src/pages/Documents.jsx index 897e9ba7f..191a862bf 100644 --- a/src/pages/Documents.jsx +++ b/src/pages/Documents.jsx @@ -13,7 +13,6 @@ import { } from '../components/Form'; import { SelectedUserContext, SignedInUserContext } from '../contexts'; import DocumentTable from '../components/Documents/DocumentTable'; -import Layout from '../layouts/Layout'; /** * Documents Page - Component that generates Documents Page for PASS @@ -23,45 +22,43 @@ import Layout from '../layouts/Layout'; * @returns {React.JSX.Element} The Documents Page */ const Documents = () => { - localStorage.setItem('restorePath', 'PASS/documents'); + localStorage.setItem('restorePath', '/documents'); const { selectedUser, setSelectedUser } = useContext(SelectedUserContext); const { podUrl } = useContext(SignedInUserContext); return ( - - + - {podUrl === selectedUser.podUrl ? ( - Personal Pod - ) : ( - Client selected: {selectedUser.person || selectedUser.podUrl} - )} + Clear Client + + {podUrl === selectedUser.podUrl ? ( + Personal Pod + ) : ( + Client selected: {selectedUser.person || selectedUser.podUrl} + )} - - - - - - + + + + + ); }; diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index ab4bd252c..62a50367c 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -4,7 +4,6 @@ import React from 'react'; import Box from '@mui/material/Box'; import Container from '@mui/material/Container'; import Paper from '@mui/material/Paper'; -import Layout from '../layouts/Layout'; /** * Home - First Page you encounter in PASS before login. @@ -15,27 +14,25 @@ import Layout from '../layouts/Layout'; * @returns {React.ReactElement} The home page */ const Home = () => ( - - - - -
-

HOME PAGE

-
-
-
-
-
+ + + +
+

HOME PAGE

+
+
+
+
); export default Home; diff --git a/src/pages/Messages.jsx b/src/pages/Messages.jsx index a5e4358d1..e9e5c7925 100644 --- a/src/pages/Messages.jsx +++ b/src/pages/Messages.jsx @@ -14,7 +14,6 @@ import { getMessageTTL } from '../utils'; import { MessageContext, SignedInUserContext } from '../contexts'; // Component Imports import { NewMessage, MessageFolder } from '../components/Messages'; -import Layout from '../layouts/Layout'; const routesArray = [{ label: 'Inbox' }, { label: 'Outbox' }]; @@ -27,7 +26,7 @@ const routesArray = [{ label: 'Inbox' }, { label: 'Outbox' }]; * @returns {React.JSX.Element} The Messages Page */ const Messages = () => { - localStorage.setItem('restorePath', '/PASS/messages'); + localStorage.setItem('restorePath', '/messages'); const { podUrl } = useContext(SignedInUserContext); @@ -71,34 +70,32 @@ const Messages = () => { const [showForm, setShowForm] = useState(false); return ( - - - - - - {routesArray.map((item) => ( - setBoxType(item.label.toLowerCase())} - /> - ))} - - - - - {showForm && setShowForm(!showForm)} />} + + + + + {routesArray.map((item) => ( + setBoxType(item.label.toLowerCase())} + /> + ))} + - + + + {showForm && setShowForm(!showForm)} />} + ); }; diff --git a/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap b/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap index c94836303..a0a7653f1 100644 --- a/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap +++ b/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap @@ -34,7 +34,7 @@ exports[`renders correctly 1`] = ` />
https://www.testurl.com/ - http://localhost:3000/PASS/ + http://localhost:3000 -
- - - -
-
-
-
-

- HOME PAGE -

-
-
-
-
- - + + `; diff --git a/vite.config.js b/vite.config.js index 01ca862a7..465ee79fe 100644 --- a/vite.config.js +++ b/vite.config.js @@ -3,7 +3,7 @@ import react from '@vitejs/plugin-react'; import visualizer from 'rollup-plugin-visualizer'; export default defineConfig({ - base: '/PASS/', + base: '/', plugins: [ react(), visualizer({ From 1d2329cd3f19fb5a85cd6c1b35665304330880aa Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Tue, 4 Jul 2023 13:06:44 -0700 Subject: [PATCH 06/13] remove solid-auth library from dependency list --- package-lock.json | 652 ++++++++++--------- package.json | 1 - src/components/NavBar/OidcLoginComponent.jsx | 2 +- vite.config.js | 4 +- 4 files changed, 349 insertions(+), 310 deletions(-) diff --git a/package-lock.json b/package-lock.json index 308fc5a50..9be657e83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,6 +60,15 @@ "vitest": "^0.31.0" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -74,46 +83,46 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", - "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", + "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz", - "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.6.tgz", + "integrity": "sha512-HPIyDa6n+HKw5dEuway3vVAhBboYCtREBMp+IWeseZy6TFtzn6MHkCH2KKYUOC/vKKwgSMHQW4htBOrmuRPXfw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.0", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.21.0", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.0", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.6", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.2" }, "engines": { "node": ">=6.9.0" @@ -124,11 +133,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", + "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", "dependencies": { - "@babel/types": "^7.21.0", + "@babel/types": "^7.22.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -149,16 +158,16 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", + "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "@babel/compat-data": "^7.22.6", + "@babel/helper-validator-option": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1" }, "engines": { "node": ">=6.9.0" @@ -168,61 +177,61 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -238,73 +247,73 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -313,9 +322,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", + "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -365,31 +374,31 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", - "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", + "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.6", + "@babel/types": "^7.22.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -398,12 +407,12 @@ } }, "node_modules/@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -4021,6 +4030,15 @@ } } }, + "node_modules/@nicolo-ribaudo/semver-v6": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", + "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -5047,9 +5065,9 @@ } }, "node_modules/@vitest/coverage-c8": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.1.tgz", - "integrity": "sha512-6TkjQpmgYez7e3dbAUoYdRXxWN81BojCmUILJwgCy39uZFG33DsQ0rSRSZC9beAEdCZTpxR63nOvd9hxDQcJ0g==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.4.tgz", + "integrity": "sha512-VPx368m4DTcpA/P0v3YdVxl4QOSh1DbUcXURLRvDShrIB5KxOgfzw4Bn2R8AhAe/GyiWW/FIsJ/OJdYXCCiC1w==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", @@ -5730,9 +5748,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, "funding": [ { @@ -5742,13 +5760,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" }, "bin": { "browserslist": "cli.js" @@ -5802,9 +5824,9 @@ } }, "node_modules/c8": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/c8/-/c8-7.13.0.tgz", - "integrity": "sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz", + "integrity": "sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -5944,9 +5966,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001459", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001459.tgz", - "integrity": "sha512-WmuS7UmOyuMxDquiA3BUKrKPBcpaIHrFnlEzlIYKecjmHMABYsqp6eeZLjcLCW5aFb/dRJNYCiuGNEssQgLfaA==", + "version": "1.0.30001512", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", + "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", "dev": true, "funding": [ { @@ -5956,6 +5978,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -6216,9 +6242,9 @@ } }, "node_modules/componentsjs/node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6274,9 +6300,9 @@ } }, "node_modules/concordance/node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6836,9 +6862,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.317", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.317.tgz", - "integrity": "sha512-JhCRm9v30FMNzQSsjl4kXaygU+qHBD0Yh7mKxyjmF0V8VwYVB6qpBRX28GyAucrM9wDCpSUctT6FpMUQxbyKuA==", + "version": "1.4.450", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz", + "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==", "dev": true }, "node_modules/emitter-component": { @@ -8161,9 +8187,9 @@ } }, "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -11517,9 +11543,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", "dev": true }, "node_modules/nodemailer": { @@ -11801,17 +11827,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -14143,9 +14169,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "funding": [ { @@ -14155,6 +14181,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { @@ -14162,7 +14192,7 @@ "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -14851,6 +14881,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -14862,48 +14898,48 @@ } }, "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.5" } }, "@babel/compat-data": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", - "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", + "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", "dev": true }, "@babel/core": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz", - "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.6.tgz", + "integrity": "sha512-HPIyDa6n+HKw5dEuway3vVAhBboYCtREBMp+IWeseZy6TFtzn6MHkCH2KKYUOC/vKKwgSMHQW4htBOrmuRPXfw==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.0", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.21.0", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.0", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.6", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.2" } }, "@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", + "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", "requires": { - "@babel/types": "^7.21.0", + "@babel/types": "^7.22.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -14918,62 +14954,62 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", + "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", "dev": true, "requires": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "@babel/compat-data": "^7.22.6", + "@babel/helper-validator-option": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1" } }, "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==" }, "@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" } }, "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "requires": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" } }, "@babel/helper-plugin-utils": { @@ -14983,63 +15019,63 @@ "dev": true }, "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "requires": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" }, "@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true }, "@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", "dev": true, "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", "requires": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==" + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", + "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==" }, "@babel/plugin-transform-react-jsx-self": { "version": "7.21.0", @@ -15068,39 +15104,39 @@ } }, "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" } }, "@babel/traverse": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", - "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", + "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", + "requires": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.6", + "@babel/types": "^7.22.5", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "requires": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" } }, @@ -18162,6 +18198,12 @@ "react-transition-group": "^4.4.5" } }, + "@nicolo-ribaudo/semver-v6": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", + "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", + "dev": true + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -19090,9 +19132,9 @@ } }, "@vitest/coverage-c8": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.1.tgz", - "integrity": "sha512-6TkjQpmgYez7e3dbAUoYdRXxWN81BojCmUILJwgCy39uZFG33DsQ0rSRSZC9beAEdCZTpxR63nOvd9hxDQcJ0g==", + "version": "0.31.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.31.4.tgz", + "integrity": "sha512-VPx368m4DTcpA/P0v3YdVxl4QOSh1DbUcXURLRvDShrIB5KxOgfzw4Bn2R8AhAe/GyiWW/FIsJ/OJdYXCCiC1w==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.1", @@ -19608,15 +19650,15 @@ } }, "browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" } }, "buffer": { @@ -19644,9 +19686,9 @@ "dev": true }, "c8": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/c8/-/c8-7.13.0.tgz", - "integrity": "sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz", + "integrity": "sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", @@ -19755,9 +19797,9 @@ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" }, "caniuse-lite": { - "version": "1.0.30001459", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001459.tgz", - "integrity": "sha512-WmuS7UmOyuMxDquiA3BUKrKPBcpaIHrFnlEzlIYKecjmHMABYsqp6eeZLjcLCW5aFb/dRJNYCiuGNEssQgLfaA==", + "version": "1.0.30001512", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", + "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", "dev": true }, "canonicalize": { @@ -19959,9 +20001,9 @@ } }, "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -20007,9 +20049,9 @@ } }, "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -20433,9 +20475,9 @@ } }, "electron-to-chromium": { - "version": "1.4.317", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.317.tgz", - "integrity": "sha512-JhCRm9v30FMNzQSsjl4kXaygU+qHBD0Yh7mKxyjmF0V8VwYVB6qpBRX28GyAucrM9wDCpSUctT6FpMUQxbyKuA==", + "version": "1.4.450", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz", + "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==", "dev": true }, "emitter-component": { @@ -21524,9 +21566,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -23930,9 +23972,9 @@ } }, "node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", "dev": true }, "nodemailer": { @@ -24133,17 +24175,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "os-tmpdir": { @@ -25935,9 +25977,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "requires": { "escalade": "^3.1.1", diff --git a/package.json b/package.json index 168765924..650de2744 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "@emotion/react": "^11.10.8", "@emotion/styled": "^11.10.8", "@inrupt/solid-client": "^1.24.0", - "@inrupt/solid-client-authn-browser": "^1.16.0", "@inrupt/solid-ui-react": "^2.8.2", "@inrupt/vocab-common-rdf": "^1.0.5", "@mui/base": "^5.0.0-beta.0", diff --git a/src/components/NavBar/OidcLoginComponent.jsx b/src/components/NavBar/OidcLoginComponent.jsx index cff307985..0a30c9346 100644 --- a/src/components/NavBar/OidcLoginComponent.jsx +++ b/src/components/NavBar/OidcLoginComponent.jsx @@ -30,7 +30,7 @@ const OidcLoginComponent = () => { }} /> - + + + + ); + /* eslint-enable jsx-a11y/label-has-associated-control */ +}; + +export default AddClient; diff --git a/src/components/Clients/AddClientModal.jsx b/src/components/Clients/AddClientModal.jsx index c4c816348..78ceca061 100644 --- a/src/components/Clients/AddClientModal.jsx +++ b/src/components/Clients/AddClientModal.jsx @@ -1,5 +1,6 @@ // React Imports import React, { useContext, useState } from 'react'; +import { useSession, useStatusNotification, useField } from '@hooks'; // Material UI Imports import Button from '@mui/material/Button'; import CheckIcon from '@mui/icons-material/Check'; @@ -12,8 +13,6 @@ import TextField from '@mui/material/TextField'; import { ENV } from '../../constants'; import { runNotification } from '../../utils'; import { createUser } from '../../model-helpers/User'; -// Custom Hook Imports -import { useStatusNotification } from '../../hooks'; // Context Imports import { UserListContext } from '../../contexts'; // Component Imports diff --git a/src/components/Documents/DocumentTableRow.jsx b/src/components/Documents/DocumentTableRow.jsx index 3f75eb865..1eb0f005d 100644 --- a/src/components/Documents/DocumentTableRow.jsx +++ b/src/components/Documents/DocumentTableRow.jsx @@ -1,7 +1,7 @@ // React Imports import React, { useContext } from 'react'; // Inrupt Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Material UI Imports import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined'; import FileOpenIcon from '@mui/icons-material/FileOpen'; diff --git a/src/components/Form/SetAclPermissionForm.jsx b/src/components/Form/SetAclPermissionForm.jsx index aa74a7875..3cd60e3ac 100644 --- a/src/components/Form/SetAclPermissionForm.jsx +++ b/src/components/Form/SetAclPermissionForm.jsx @@ -1,7 +1,6 @@ // React Imports import React, { useContext, useState } from 'react'; -// Inrupt Library Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession, useStatusNotification } from '@hooks'; // Material UI Imports import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -14,9 +13,6 @@ import RadioGroup from '@mui/material/RadioGroup'; import TextField from '@mui/material/TextField'; // Utility Imports import { getPodUrl, runNotification, setDocAclPermission } from '../../utils'; -// Custom Hook Imports -import { useStatusNotification } from '../../hooks'; -// Context Imports import { SelectedUserContext, SignedInUserContext } from '../../contexts'; // Component Imports import DocumentSelection from './DocumentSelection'; diff --git a/src/components/Form/SetAclPermsDocContainerForm.jsx b/src/components/Form/SetAclPermsDocContainerForm.jsx index 5481add2b..01536009a 100644 --- a/src/components/Form/SetAclPermsDocContainerForm.jsx +++ b/src/components/Form/SetAclPermsDocContainerForm.jsx @@ -1,7 +1,7 @@ // React Imports import React, { useContext, useState } from 'react'; // Inrupt Library Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession, useStatusNotification } from '@hooks'; // Material UI Imports import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -14,8 +14,6 @@ import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; // Utility Imports import { getPodUrl, runNotification, setDocContainerAclPermission } from '../../utils'; -// Custom Hook Imports -import { useStatusNotification } from '../../hooks'; // Context Imports import { SelectedUserContext, SignedInUserContext } from '../../contexts'; // Component Imports diff --git a/src/components/LogoutModal/LogoutButton.jsx b/src/components/LogoutModal/LogoutButton.jsx new file mode 100644 index 000000000..a8ee1bf06 --- /dev/null +++ b/src/components/LogoutModal/LogoutButton.jsx @@ -0,0 +1,63 @@ +/** + * Copyright 2020 Inrupt Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import React, { useContext } from "react"; +import { SessionContext } from "@contexts"; + +const LogoutButton = ({ + children, + onLogout, + onError, +}) => { + const { logout } = useContext(SessionContext); + + const logoutHandler = async () => { + try { + await logout(); + if (onLogout) onLogout(); + } catch (error) { + if (onError) onError(error); + } + } + + const keyDownHandler = (e) => { + e.preventDefault(); + + return e.key === "Enter" ? logoutHandler() : Promise.resolve(); + } + + return children ? ( +
+ {children} +
+ ) : ( + + ); +}; + +export default LogoutButton; diff --git a/src/components/LogoutModal/LogoutModal.jsx b/src/components/LogoutModal/LogoutModal.jsx index b2ca3f6bd..44d417696 100644 --- a/src/components/LogoutModal/LogoutModal.jsx +++ b/src/components/LogoutModal/LogoutModal.jsx @@ -1,7 +1,5 @@ // React Imports import React from 'react'; -// Solid Imports -import { LogoutButton } from '@inrupt/solid-ui-react'; // Material UI Imports import Button from '@mui/material/Button'; import Dialog from '@mui/material/Dialog'; @@ -12,6 +10,8 @@ import DialogTitle from '@mui/material/DialogTitle'; import ClearIcon from '@mui/icons-material/Clear'; import CheckIcon from '@mui/icons-material/Check'; +import LogoutButton from './LogoutButton'; + /** * LogoutModal Component - Popup modal for users to confirm * they actually want to logout of their Solid Pod @@ -44,7 +44,6 @@ const LogoutModal = ({ showConfirmation, setShowConfirmation, handleLogout }) => > NO - {/* NECESSARY WRAPPER FOR SOLID/POD LOGOUT FUNCTIONALITY */} -
); }; diff --git a/src/components/Notification/InactivityMessage.jsx b/src/components/Notification/InactivityMessage.jsx index 0a1138c23..5d8bc91ec 100644 --- a/src/components/Notification/InactivityMessage.jsx +++ b/src/components/Notification/InactivityMessage.jsx @@ -1,7 +1,5 @@ // React Imports import React, { useState, useEffect } from 'react'; -// Inrupt Library Imports -import { LogoutButton } from '@inrupt/solid-ui-react'; // Material UI Imports import Button from '@mui/material/Button'; import Dialog from '@mui/material/Dialog'; @@ -12,6 +10,7 @@ import DialogTitle from '@mui/material/DialogTitle'; import CheckIcon from '@mui/icons-material/Check'; import LogoutIcon from '@mui/icons-material/Logout'; +import LogoutButton from '../LogoutModal/LogoutButton'; /** * Inactivity Notification Component - Component that displays a popup modal * after 30 minutes of inactivity, prompting the user to either logout or diff --git a/src/contexts/DocumentListContext.jsx b/src/contexts/DocumentListContext.jsx index 38b0f152c..c6f6cfdb3 100644 --- a/src/contexts/DocumentListContext.jsx +++ b/src/contexts/DocumentListContext.jsx @@ -2,7 +2,7 @@ import React, { createContext, useState, useMemo, useEffect, useContext } from 'react'; import { createSolidDataset } from '@inrupt/solid-client'; // Inrupt Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Context Imports import { SelectedUserContext } from './SelectedUserContext'; diff --git a/src/contexts/MessageContext.jsx b/src/contexts/MessageContext.jsx index 1ae73c81b..c6f6fdb3e 100644 --- a/src/contexts/MessageContext.jsx +++ b/src/contexts/MessageContext.jsx @@ -1,7 +1,7 @@ // React Imports import React, { createContext, useContext, useMemo, useEffect, useState } from 'react'; // Inrupt Library Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Utility Imports import { createOutbox, createInbox, getMessageTTL } from '../utils'; // Context Imports diff --git a/src/contexts/SessionContext.jsx b/src/contexts/SessionContext.jsx new file mode 100644 index 000000000..21e64ef37 --- /dev/null +++ b/src/contexts/SessionContext.jsx @@ -0,0 +1,177 @@ +/** + * Copyright 2020 Inrupt Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import React, { + createContext, + useState, + useEffect, + useMemo +} from "react"; + +import { + fetch, + login, + logout, + handleIncomingRedirect, + getDefaultSession, + onSessionRestore as onSessionRestoreClient, +} from "@inrupt/solid-client-authn-browser"; + +import { + getProfileAll, +} from "@inrupt/solid-client"; + +export const SessionContext = createContext({ + login, + logout, + fetch, + session: getDefaultSession(), + sessionRequestInProgress: true, + profile: undefined, +}); + +export const SessionProvider = ({ + sessionId, + children, + onError, + sessionRequestInProgress: defaultSessionRequestInProgress, + restorePreviousSession, + skipLoadingProfile, + onSessionRestore, +}) => { + const restoreSession = + restorePreviousSession || typeof onSessionRestore !== "undefined"; + const [session, setSession] = useState(getDefaultSession()); + const [profile, setProfile] = + useState(); + + useEffect(() => { + if (onSessionRestore !== undefined) { + onSessionRestoreClient(onSessionRestore); + } + }, [onSessionRestore]); + + const defaultInProgress = + typeof defaultSessionRequestInProgress === "undefined" + ? !session.info.isLoggedIn + : defaultSessionRequestInProgress; + + // If loggedin is true, we're not making a session request. + const [sessionRequestInProgress, setSessionRequestInProgress] = + useState(defaultInProgress); + + let currentLocation; + + if (typeof window !== "undefined") { + currentLocation = window.location; + } + useEffect(() => { + console.log('handling redirect'); + handleIncomingRedirect({ + url: window.location.href, + restorePreviousSession: restoreSession, + }) + .then(async (sessionInfo) => { + console.log(`handled redirect: ${JSON.stringify(sessionInfo)}`); + if (skipLoadingProfile === true) { + return; + } + + // If handleIncomingRedirect logged the session in, we know what the current + // user's WebID is. + if (sessionInfo?.webId !== undefined) { + const profiles = await getProfileAll(sessionInfo?.webId, { + fetch: session.fetch, + }); + + setProfile(profiles); + } + }) + .catch((error) => { + if (onError) { + onError(error); + } else { + throw error; + } + }) + .finally(() => { + setSessionRequestInProgress(false); + }); + + getDefaultSession().on("logout", () => { + setSession(getDefaultSession()); + }); + }, [ + session, + sessionId, + onError, + currentLocation, + restoreSession, + skipLoadingProfile, + ]); + + const contextLogin = async (options) => { + setSessionRequestInProgress(true); + + try { + await login(options); + } catch (error) { + if (onError) { + onError(error); + } else { + throw error; + } + } finally { + setSessionRequestInProgress(false); + } + }; + + const contextLogout = async () => { + try { + await logout(); + setProfile(undefined); + } catch (error) { + if (onError) { + onError(error); + } else { + throw error; + } + } + }; + + const sessionMemo = useMemo( () => ({ + session, + login: contextLogin, + logout: contextLogout, + sessionRequestInProgress, + setSessionRequestInProgress, + fetch, + profile + }), [session, profile, sessionRequestInProgress]) + + return ( + + {children} + + ); +}; diff --git a/src/contexts/SignedInUserContext.jsx b/src/contexts/SignedInUserContext.jsx index e7534725a..5a8c56fed 100644 --- a/src/contexts/SignedInUserContext.jsx +++ b/src/contexts/SignedInUserContext.jsx @@ -1,7 +1,7 @@ // React Imports import React, { createContext, useState, useMemo, useEffect } from 'react'; // Inrupt Library Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; import { getPodUrlAll } from '@inrupt/solid-client'; // Utility Imports import { createPublicContainer } from '../utils'; diff --git a/src/contexts/UserListContext.jsx b/src/contexts/UserListContext.jsx index 25a128516..767fc28f2 100644 --- a/src/contexts/UserListContext.jsx +++ b/src/contexts/UserListContext.jsx @@ -1,7 +1,7 @@ // React Imports import React, { createContext, useState, useMemo, useEffect, useContext } from 'react'; // Inrupt Library Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Utility Imports import { loadUserList, addUser, removeUser } from '../model-helpers'; // Context Imports diff --git a/src/contexts/index.js b/src/contexts/index.js index bde5bebcc..9782c8e47 100644 --- a/src/contexts/index.js +++ b/src/contexts/index.js @@ -10,3 +10,4 @@ export * from './SelectedUserContext'; export * from './UserListContext'; export * from './MessageContext'; export * from './DocumentListContext'; +export * from './SessionContext'; diff --git a/src/hooks/index.js b/src/hooks/index.js index 60df6464e..10ea7da16 100644 --- a/src/hooks/index.js +++ b/src/hooks/index.js @@ -1,6 +1,6 @@ import useField from './useField'; import useStatusNotification from './useStatusNotification'; - +import useSession from './useSession'; /** * The hooks module contains custom hooks to assist with form handling or status * notifications @@ -8,4 +8,4 @@ import useStatusNotification from './useStatusNotification'; * @namespace hooks */ -export { useField, useStatusNotification }; +export { useField, useStatusNotification, useSession }; diff --git a/src/hooks/useSession.js b/src/hooks/useSession.js new file mode 100644 index 000000000..942481e11 --- /dev/null +++ b/src/hooks/useSession.js @@ -0,0 +1,38 @@ +/** + * Copyright 2020 Inrupt Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { useContext } from "react"; +import { SessionContext } from "../contexts/SessionContext"; + +const useSession = () => { + const { session, sessionRequestInProgress, fetch, login, logout } = + useContext(SessionContext); + + return { + session, + sessionRequestInProgress, + fetch, + login, + logout, + }; +} + +export default useSession; diff --git a/src/index.jsx b/src/index.jsx index 852061091..a23e0a2ec 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -9,7 +9,5 @@ import './style.css'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - - ); diff --git a/src/layouts/Layout.jsx b/src/layouts/Layout.jsx index d7e07321f..3ce40596e 100644 --- a/src/layouts/Layout.jsx +++ b/src/layouts/Layout.jsx @@ -1,7 +1,7 @@ // React Imports import React from 'react'; // Inrupt Library Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Material UI Imports import Box from '@mui/material/Box'; // Component Imports diff --git a/src/pages/Messages.jsx b/src/pages/Messages.jsx index e9e5c7925..16ff4722f 100644 --- a/src/pages/Messages.jsx +++ b/src/pages/Messages.jsx @@ -1,7 +1,7 @@ // React Imports import React, { useContext, useState, useEffect } from 'react'; // Inrupt Library Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Material UI Imports import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; diff --git a/test/contexts/SignedInUserContext.test.jsx b/test/contexts/SignedInUserContext.test.jsx index fc5f387c0..0600551b8 100644 --- a/test/contexts/SignedInUserContext.test.jsx +++ b/test/contexts/SignedInUserContext.test.jsx @@ -8,7 +8,7 @@ import { buildThing, createThing } from '@inrupt/solid-client'; -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; import { expect, it, afterEach, describe, vi } from 'vitest'; import { SignedInUserContext, SignedInUserContextProvider } from '../../src/contexts'; import { RDF_PREDICATES } from '../../src/constants'; diff --git a/vite.config.js b/vite.config.js index f26d2bbfc..07ef3df77 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,6 +1,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import visualizer from 'rollup-plugin-visualizer'; +import { resolve } from "path"; export default defineConfig({ plugins: [ @@ -9,6 +10,15 @@ export default defineConfig({ filename: 'bundleStats.html' }) ], + resolve:{ + alias:{ + "@hooks": resolve(__dirname, "src/hooks"), + "@contexts": resolve(__dirname, "src/contexts"), + "@pages": resolve(__dirname, "src/pages"), + "@utils": resolve(__dirname, "src/utils"), + "@components": resolve(__dirname,"src/components") + } + }, test: { environment: 'jsdom' } From 2c130212add6057c9886f0cd45d958fe8458e229 Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Mon, 10 Jul 2023 11:29:11 -0700 Subject: [PATCH 08/13] fix build config to convert solid-client-authn-browser to ESM --- package-lock.json | 178 +++++++++++++++++++ package.json | 1 + src/components/LogoutModal/LogoutButton.jsx | 23 +-- src/components/NavBar/OidcLoginComponent.jsx | 52 +++--- src/contexts/SessionContext.jsx | 78 +++----- src/hooks/useSession.js | 11 +- src/index.jsx | 4 +- vite.config.js | 29 ++- 8 files changed, 262 insertions(+), 114 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd4fbd09b..79fa638a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "uuid": "^9.0.0" }, "devDependencies": { + "@rollup/plugin-node-resolve": "^15.1.0", "@solid/community-server": "^5.1.0", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", @@ -4154,6 +4155,53 @@ "node": ">=14" } }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", + "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@sinclair/typebox": { "version": "0.25.24", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", @@ -4607,6 +4655,12 @@ "@types/node": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, "node_modules/@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -4963,6 +5017,12 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -5857,6 +5917,18 @@ "ieee754": "^1.1.13" } }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -6708,6 +6780,15 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/default-browser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", @@ -8771,6 +8852,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -10040,6 +10127,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -10180,6 +10282,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -18801,6 +18909,31 @@ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz", "integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==" }, + "@rollup/plugin-node-resolve": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", + "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + } + }, + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, "@sinclair/typebox": { "version": "0.25.24", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", @@ -19183,6 +19316,12 @@ "@types/node": "*" } }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, "@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -19540,6 +19679,12 @@ } } }, + "@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -20223,6 +20368,12 @@ "ieee754": "^1.1.13" } }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true + }, "bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -20876,6 +21027,12 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, "default-browser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", @@ -22411,6 +22568,12 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -23352,6 +23515,15 @@ "has-tostringtag": "^1.0.0" } }, + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -23434,6 +23606,12 @@ "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", diff --git a/package.json b/package.json index 0246ce0c3..3b745e08c 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "last 3 edge versions" ], "devDependencies": { + "@rollup/plugin-node-resolve": "^15.1.0", "@solid/community-server": "^5.1.0", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", diff --git a/src/components/LogoutModal/LogoutButton.jsx b/src/components/LogoutModal/LogoutButton.jsx index a8ee1bf06..e8bf37a6c 100644 --- a/src/components/LogoutModal/LogoutButton.jsx +++ b/src/components/LogoutModal/LogoutButton.jsx @@ -19,14 +19,10 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import React, { useContext } from "react"; -import { SessionContext } from "@contexts"; +import React, { useContext } from 'react'; +import { SessionContext } from '@contexts'; -const LogoutButton = ({ - children, - onLogout, - onError, -}) => { +const LogoutButton = ({ children, onLogout, onError }) => { const { logout } = useContext(SessionContext); const logoutHandler = async () => { @@ -36,21 +32,16 @@ const LogoutButton = ({ } catch (error) { if (onError) onError(error); } - } + }; const keyDownHandler = (e) => { e.preventDefault(); - return e.key === "Enter" ? logoutHandler() : Promise.resolve(); - } + return e.key === 'Enter' ? logoutHandler() : Promise.resolve(); + }; return children ? ( -
+
{children}
) : ( diff --git a/src/components/NavBar/OidcLoginComponent.jsx b/src/components/NavBar/OidcLoginComponent.jsx index 930112175..33b3e076d 100644 --- a/src/components/NavBar/OidcLoginComponent.jsx +++ b/src/components/NavBar/OidcLoginComponent.jsx @@ -8,26 +8,14 @@ import { TextField, Box, Button } from '@mui/material'; import { ENV } from '../../constants'; const OidcLoginComponent = () => { - const { login } = useSession(); + const { login } = useSession(); const defaultOidc = ENV.VITE_SOLID_IDENTITY_PROVIDER || ''; const [oidcIssuer, setOidcIssuer] = useState(defaultOidc); const loginHandler = async () => { - window.console.log(`logging in with: ${oidcIssuer}`); const redirectUrl = window.location.href; - try { - const loginResult = await login( - {oidcIssuer, - redirectUrl} - ) - window.console.log(loginResult); - localStorage.setItem('oidcIssuer', oidcIssuer); - } catch(e) { - console.error(e); - } - finally{ - window.console.log('login complete'); - } - } + await login({ oidcIssuer, redirectUrl }); + localStorage.setItem('oidcIssuer', oidcIssuer); + }; return ( <> @@ -47,23 +35,23 @@ const OidcLoginComponent = () => { }} /> - + } + }} + > + Login + ); }; diff --git a/src/contexts/SessionContext.jsx b/src/contexts/SessionContext.jsx index 21e64ef37..e38f1fe6d 100644 --- a/src/contexts/SessionContext.jsx +++ b/src/contexts/SessionContext.jsx @@ -19,12 +19,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import React, { - createContext, - useState, - useEffect, - useMemo -} from "react"; +import React, { createContext, useState, useEffect, useMemo } from 'react'; import { fetch, @@ -32,12 +27,10 @@ import { logout, handleIncomingRedirect, getDefaultSession, - onSessionRestore as onSessionRestoreClient, -} from "@inrupt/solid-client-authn-browser"; + onSessionRestore as onSessionRestoreClient +} from '@inrupt/solid-client-authn-browser'; -import { - getProfileAll, -} from "@inrupt/solid-client"; +import { getProfileAll } from '@inrupt/solid-client'; export const SessionContext = createContext({ login, @@ -45,7 +38,7 @@ export const SessionContext = createContext({ fetch, session: getDefaultSession(), sessionRequestInProgress: true, - profile: undefined, + profile: undefined }); export const SessionProvider = ({ @@ -55,13 +48,11 @@ export const SessionProvider = ({ sessionRequestInProgress: defaultSessionRequestInProgress, restorePreviousSession, skipLoadingProfile, - onSessionRestore, + onSessionRestore }) => { - const restoreSession = - restorePreviousSession || typeof onSessionRestore !== "undefined"; + const restoreSession = restorePreviousSession || typeof onSessionRestore !== 'undefined'; const [session, setSession] = useState(getDefaultSession()); - const [profile, setProfile] = - useState(); + const [profile, setProfile] = useState(); useEffect(() => { if (onSessionRestore !== undefined) { @@ -70,27 +61,24 @@ export const SessionProvider = ({ }, [onSessionRestore]); const defaultInProgress = - typeof defaultSessionRequestInProgress === "undefined" + typeof defaultSessionRequestInProgress === 'undefined' ? !session.info.isLoggedIn : defaultSessionRequestInProgress; // If loggedin is true, we're not making a session request. - const [sessionRequestInProgress, setSessionRequestInProgress] = - useState(defaultInProgress); + const [sessionRequestInProgress, setSessionRequestInProgress] = useState(defaultInProgress); let currentLocation; - if (typeof window !== "undefined") { + if (typeof window !== 'undefined') { currentLocation = window.location; } useEffect(() => { - console.log('handling redirect'); handleIncomingRedirect({ url: window.location.href, - restorePreviousSession: restoreSession, + restorePreviousSession: restoreSession }) .then(async (sessionInfo) => { - console.log(`handled redirect: ${JSON.stringify(sessionInfo)}`); if (skipLoadingProfile === true) { return; } @@ -99,7 +87,7 @@ export const SessionProvider = ({ // user's WebID is. if (sessionInfo?.webId !== undefined) { const profiles = await getProfileAll(sessionInfo?.webId, { - fetch: session.fetch, + fetch: session.fetch }); setProfile(profiles); @@ -116,17 +104,10 @@ export const SessionProvider = ({ setSessionRequestInProgress(false); }); - getDefaultSession().on("logout", () => { + getDefaultSession().on('logout', () => { setSession(getDefaultSession()); }); - }, [ - session, - sessionId, - onError, - currentLocation, - restoreSession, - skipLoadingProfile, - ]); + }, [session, sessionId, onError, currentLocation, restoreSession, skipLoadingProfile]); const contextLogin = async (options) => { setSessionRequestInProgress(true); @@ -157,21 +138,18 @@ export const SessionProvider = ({ } }; - const sessionMemo = useMemo( () => ({ - session, - login: contextLogin, - logout: contextLogout, - sessionRequestInProgress, - setSessionRequestInProgress, - fetch, - profile - }), [session, profile, sessionRequestInProgress]) - - return ( - - {children} - + const sessionMemo = useMemo( + () => ({ + session, + login: contextLogin, + logout: contextLogout, + sessionRequestInProgress, + setSessionRequestInProgress, + fetch, + profile + }), + [session, profile, sessionRequestInProgress] ); + + return {children}; }; diff --git a/src/hooks/useSession.js b/src/hooks/useSession.js index 942481e11..23e06e15c 100644 --- a/src/hooks/useSession.js +++ b/src/hooks/useSession.js @@ -19,20 +19,19 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { useContext } from "react"; -import { SessionContext } from "../contexts/SessionContext"; +import { useContext } from 'react'; +import { SessionContext } from '../contexts/SessionContext'; const useSession = () => { - const { session, sessionRequestInProgress, fetch, login, logout } = - useContext(SessionContext); + const { session, sessionRequestInProgress, fetch, login, logout } = useContext(SessionContext); return { session, sessionRequestInProgress, fetch, login, - logout, + logout }; -} +}; export default useSession; diff --git a/src/index.jsx b/src/index.jsx index a23e0a2ec..b87361a60 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -8,6 +8,4 @@ import App from './App'; import './style.css'; const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - -); +root.render(); diff --git a/vite.config.js b/vite.config.js index 07ef3df77..db32016fa 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,6 +2,18 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import visualizer from 'rollup-plugin-visualizer'; import { resolve } from "path"; +import { nodeResolve } from '@rollup/plugin-node-resolve'; + +// Workaround for this open solid-client-authn bug: +// https://github.com/inrupt/solid-client-authn-js/issues/3001 +// Once that issue is fixed and the solid-client-authn-js version is bumped +// We can delete this function and all related code +function withCustomResolver( + { find, exportConditions, mainFields } +) { + const customResolver = nodeResolve({exportConditions, mainFields }) + return { find, replacement: find, customResolver } +} export default defineConfig({ plugins: [ @@ -11,15 +23,18 @@ export default defineConfig({ }) ], resolve:{ - alias:{ - "@hooks": resolve(__dirname, "src/hooks"), - "@contexts": resolve(__dirname, "src/contexts"), - "@pages": resolve(__dirname, "src/pages"), - "@utils": resolve(__dirname, "src/utils"), - "@components": resolve(__dirname,"src/components") - } + alias:[ + {find: "@hooks", replacement: resolve(__dirname, "src/hooks")}, + {find: "@contexts", replacement: resolve(__dirname, "src/contexts")}, + {find: "@pages", replacement: resolve(__dirname, "src/pages")}, + {find: "@utils", replacement: resolve(__dirname, "src/utils")}, + {find: "@components", replacement: resolve(__dirname,"src/components")}, + withCustomResolver({find: '@inrupt/solid-client', exportConditions: ['import']}), + withCustomResolver({find: '@inrupt/solid-client-authn-core', exportConditions: ['import']}) + ] }, test: { environment: 'jsdom' } }); + From 7368c22f7aacb12caa72f353d453137802d76f88 Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Mon, 10 Jul 2023 11:47:33 -0700 Subject: [PATCH 09/13] updates from rebase --- src/components/Clients/AddClient.jsx | 182 ------------------- src/components/Clients/AddClientModal.jsx | 2 +- src/components/NavBar/NavMenu.jsx | 2 - src/components/Profile/ProfileImageField.jsx | 2 +- src/pages/Profile.jsx | 3 +- 5 files changed, 3 insertions(+), 188 deletions(-) delete mode 100644 src/components/Clients/AddClient.jsx diff --git a/src/components/Clients/AddClient.jsx b/src/components/Clients/AddClient.jsx deleted file mode 100644 index c31052012..000000000 --- a/src/components/Clients/AddClient.jsx +++ /dev/null @@ -1,182 +0,0 @@ -// React Imports -import React, { useContext, useState } from 'react'; -import { useStatusNotification, useField, useSession } from '@hooks'; -// Utility Imports -import { ENV } from '../../constants'; -import { runNotification } from '../../utils'; -import { createUser } from '../../model-helpers/User'; -// Custom Hook Imports -// Context Imports -import { UserListContext } from '../../contexts'; -// Component Imports -import FormSection from '../Form/FormSection'; - -/** - * AddClient Component - Component that allows users to add other user's - * Pod URLs from a user's list stored on their own Pod - * - * @memberof Forms - * @name AddClient - */ - -const renderWebId = (username) => { - const oidcProvider = ENV.VITE_SOLID_IDENTITY_PROVIDER.split('//')[1]; - const template = ['https://', `.${oidcProvider}profile/card#me`]; - return `${template[0]}${username}${template[1]}`; -}; - -const AddClient = () => { - const { session } = useSession(); - const { state, dispatch } = useStatusNotification(); - const { clearValue: clearUserGivenName, ...userGivenName } = useField('text'); - const { clearValue: clearUserFamilyName, ...userFamilyName } = useField('text'); - const [username, setUsername] = useState(''); - const [webId, setWebId] = useState(''); - const { addUser } = useContext(UserListContext); - - const wrappedSetUsername = (value) => { - setUsername(value); - const renderedWebId = renderWebId(value); - setWebId(renderedWebId); - }; - - const submitUser = async (userObject) => { - const user = await createUser(session, userObject); - await addUser(user); - }; - - const notifyStartSubmission = (userObject) => { - // ===== START OF ERROR DISPLAY OPTIONS ===== - if (!userObject.username && !userObject.webId) { - runNotification(`Operation failed. Reason: No WebId provided`, 5, state, dispatch); - return; - } - - if (!userObject.givenName) { - runNotification( - `Operation failed. Reason: User's first/given name is not provided`, - 5, - state, - dispatch - ); - setTimeout(() => { - dispatch({ type: 'CLEAR_PROCESSING' }); - }, 3000); - return; - } - - if (!userObject.familyName) { - runNotification( - `Operation failed. Reason: User's last/family name is not provided`, - 5, - state, - dispatch - ); - setTimeout(() => { - dispatch({ type: 'CLEAR_PROCESSING' }); - }, 3000); - return; - } - // ===== END OF ERROR DISPLAY OPTIONS ===== - - dispatch({ type: 'SET_PROCESSING' }); - - runNotification( - `Adding "${userObject.givenName} ${userObject.familyName}" to client list...`, - 5, - state, - dispatch - ); - }; - - // Event handler for adding client to users list - const handleAddClient = async (event) => { - event.preventDefault(); - const userObject = { - givenName: event.target.addUserGivenName.value, - familyName: event.target.addUserFamilyName.value, - username: event.target.addUsername.value, - webId: event.target.addWebId.value - }; - - notifyStartSubmission(userObject, state, dispatch); - try { - await submitUser(userObject); - } finally { - runNotification( - `"${userObject.givenName} ${userObject.familyName}" added to client list`, - 5, - state, - dispatch - ); - setTimeout(() => { - clearUserGivenName(); - clearUserFamilyName(); - setUsername(''); - setWebId(''); - dispatch({ type: 'CLEAR_PROCESSING' }); - }, 3000); - } - }; - - /* eslint-disable jsx-a11y/label-has-associated-control */ - return ( - -
-
- - -
-
-
- - -
-
-
- -
-
- wrappedSetUsername(e.target.value)} - /> -
-
- -
- -
-
- ); - /* eslint-enable jsx-a11y/label-has-associated-control */ -}; - -export default AddClient; diff --git a/src/components/Clients/AddClientModal.jsx b/src/components/Clients/AddClientModal.jsx index 78ceca061..02a6c6c16 100644 --- a/src/components/Clients/AddClientModal.jsx +++ b/src/components/Clients/AddClientModal.jsx @@ -1,6 +1,6 @@ // React Imports import React, { useContext, useState } from 'react'; -import { useSession, useStatusNotification, useField } from '@hooks'; +import { useStatusNotification } from '@hooks'; // Material UI Imports import Button from '@mui/material/Button'; import CheckIcon from '@mui/icons-material/Check'; diff --git a/src/components/NavBar/NavMenu.jsx b/src/components/NavBar/NavMenu.jsx index 023b626f8..5c1a5fec0 100644 --- a/src/components/NavBar/NavMenu.jsx +++ b/src/components/NavBar/NavMenu.jsx @@ -1,8 +1,6 @@ // React Imports import React from 'react'; import { NavLink } from 'react-router-dom'; -// Inrupt Library Imports -import { useSession } from '@hooks'; // Material UI Imports import Avatar from '@mui/material/Avatar'; import Button from '@mui/material/Button'; diff --git a/src/components/Profile/ProfileImageField.jsx b/src/components/Profile/ProfileImageField.jsx index c038f0d8f..53e4a18a6 100644 --- a/src/components/Profile/ProfileImageField.jsx +++ b/src/components/Profile/ProfileImageField.jsx @@ -1,7 +1,7 @@ // React Imports import React, { useContext, useState } from 'react'; // Inrupt Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Material UI Imports import Avatar from '@mui/material/Avatar'; import Box from '@mui/material/Box'; diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx index 7798082da..e0653d9f5 100644 --- a/src/pages/Profile.jsx +++ b/src/pages/Profile.jsx @@ -1,8 +1,7 @@ // React Imports import React, { useContext, useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; -// Inrupt Imports -import { useSession } from '@inrupt/solid-ui-react'; +import { useSession } from '@hooks'; // Material UI Imports import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; From 773311064e85c30b9003f194608fd400e1b12887 Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Mon, 10 Jul 2023 13:01:28 -0700 Subject: [PATCH 10/13] add netlify redirect file --- public/_redirects | 1 + 1 file changed, 1 insertion(+) create mode 100644 public/_redirects diff --git a/public/_redirects b/public/_redirects new file mode 100644 index 000000000..7797f7c6a --- /dev/null +++ b/public/_redirects @@ -0,0 +1 @@ +/* /index.html 200 From c6d45918d42501350b0a700a7c1281e7de1c18f9 Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Mon, 10 Jul 2023 14:34:58 -0700 Subject: [PATCH 11/13] update to use different netlify config --- netlify.toml | 4 ++++ public/_redirects | 1 - src/index.jsx | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 netlify.toml delete mode 100644 public/_redirects diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 000000000..1cb2010f3 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,4 @@ +[[redirects]] + from = "/*" + to = "/" + status = 200 diff --git a/public/_redirects b/public/_redirects deleted file mode 100644 index 7797f7c6a..000000000 --- a/public/_redirects +++ /dev/null @@ -1 +0,0 @@ -/* /index.html 200 diff --git a/src/index.jsx b/src/index.jsx index b87361a60..852061091 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -8,4 +8,8 @@ import App from './App'; import './style.css'; const root = ReactDOM.createRoot(document.getElementById('root')); -root.render(); +root.render( + + + +); From 11d65086e0934985d346c14c2aae9fb29c8eaf6e Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Mon, 10 Jul 2023 17:01:27 -0700 Subject: [PATCH 12/13] fix broken tests --- .../@inrupt/solid-client-authn-browser.js | 5 + .../NavBar/OidcLoginComponent.test.jsx | 30 ++--- .../OidcLoginComponent.test.jsx.snap | 110 ------------------ test/contexts/SignedInUserContext.test.jsx | 19 +-- 4 files changed, 17 insertions(+), 147 deletions(-) create mode 100644 __mocks__/@inrupt/solid-client-authn-browser.js delete mode 100644 test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap diff --git a/__mocks__/@inrupt/solid-client-authn-browser.js b/__mocks__/@inrupt/solid-client-authn-browser.js new file mode 100644 index 000000000..11a46b95b --- /dev/null +++ b/__mocks__/@inrupt/solid-client-authn-browser.js @@ -0,0 +1,5 @@ +import { vi } from 'vitest'; + +export * from '@inrupt/solid-client-authn-browser'; + +export const login = vi.fn(() => Promise.resolve()); diff --git a/test/components/NavBar/OidcLoginComponent.test.jsx b/test/components/NavBar/OidcLoginComponent.test.jsx index 29103087b..62dd497a8 100644 --- a/test/components/NavBar/OidcLoginComponent.test.jsx +++ b/test/components/NavBar/OidcLoginComponent.test.jsx @@ -1,18 +1,11 @@ import { render, cleanup } from '@testing-library/react'; +import { login } from '@inrupt/solid-client-authn-browser'; import userEvent from '@testing-library/user-event'; import React from 'react'; import { expect, it, vi, afterEach } from 'vitest'; import OidcLoginComponent from '../../../src/components/NavBar/OidcLoginComponent'; -vi.mock('@inrupt/solid-ui-react', () => ({ - LoginButton: ({ children, oidcIssuer, redirectUrl }) => ( -
- {oidcIssuer} - {redirectUrl} - {children} -
- ) -})); +vi.mock('@inrupt/solid-client-authn-browser'); afterEach(() => { vi.clearAllMocks(); @@ -30,21 +23,16 @@ vi.mock('../../../src/constants/', () => { }; }); -it('renders correctly', () => { - const { container } = render(); - expect(container).toMatchSnapshot(); -}); - it('sets OIDC provider on login', async () => { const user = userEvent.setup(); - const { container, getByLabelText } = render(); + const { getByLabelText } = render(); const input = getByLabelText('OIDC Input Field').querySelector('input'); - const login = getByLabelText('Login Button'); + const loginButton = getByLabelText('Login Button'); vi.spyOn(Storage.prototype, 'setItem'); await user.clear(input); - await user.type(input, 'oidc.provider.url'); - expect(input.value).toBe('oidc.provider.url'); - await user.click(login); - expect(localStorage.setItem).toBeCalledWith('oidcIssuer', 'oidc.provider.url'); - expect(container).toMatchSnapshot(); + await user.type(input, 'http://oidc.provider.url/'); + expect(input.value).toBe('http://oidc.provider.url/'); + await user.click(loginButton); + expect(login).toBeCalled(); + expect(localStorage.setItem).toBeCalledWith('oidcIssuer', 'http://oidc.provider.url/'); }); diff --git a/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap b/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap deleted file mode 100644 index a0a7653f1..000000000 --- a/test/components/NavBar/__snapshots__/OidcLoginComponent.test.jsx.snap +++ /dev/null @@ -1,110 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`renders correctly 1`] = ` -
-
-
- -
- -
-
-
-
- https://www.testurl.com/ - http://localhost:3000 - -
-
-`; - -exports[`sets OIDC provider on login 1`] = ` -
-
-
- -
- -
-
-
-
- oidc.provider.url - http://localhost:3000 - -
-
-`; diff --git a/test/contexts/SignedInUserContext.test.jsx b/test/contexts/SignedInUserContext.test.jsx index 0600551b8..50079b873 100644 --- a/test/contexts/SignedInUserContext.test.jsx +++ b/test/contexts/SignedInUserContext.test.jsx @@ -21,22 +21,9 @@ const TestConsumer = () => { }; vi.mock('@inrupt/solid-client'); - -vi.mock('@inrupt/solid-ui-react', async () => { - const lib = await vi.importActual('@inrupt/solid-ui-react'); - return { - ...lib, - useSession: vi.fn(() => ({ - session: { - fetch: vi.fn(), - info: { - isLoggedIn: false, - webId: 'https://example.com/pod/profile/card#me' - } - } - })) - }; -}); +vi.mock('@hooks', () => ({ + useSession: vi.fn() +})); describe('SignedInUserContext', () => { afterEach(() => { From ae6a47fa2a63d911642ef06f1b5bc4ce617c4d57 Mon Sep 17 00:00:00 2001 From: Tim Standen Date: Thu, 20 Jul 2023 15:38:06 -0700 Subject: [PATCH 13/13] remove netlify config --- netlify.toml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 netlify.toml diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index 1cb2010f3..000000000 --- a/netlify.toml +++ /dev/null @@ -1,4 +0,0 @@ -[[redirects]] - from = "/*" - to = "/" - status = 200