diff --git a/.env b/.env new file mode 100644 index 00000000..d72dbacc --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +VITE_API_URL=https://api.revolt.chat +VITE_THEMES_URL=https://static.revolt.chat/themes diff --git a/package.json b/package.json index 388e987f..62948954 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@types/node": "^15.12.3", "@types/preact-i18n": "^2.3.0", "@types/react-helmet": "^6.1.1", + "@types/react-router-dom": "^5.1.7", "@types/styled-components": "^5.1.10", "@typescript-eslint/eslint-plugin": "^4.27.0", "@typescript-eslint/parser": "^4.27.0", @@ -44,6 +45,7 @@ "react-helmet": "^6.1.0", "react-overlapping-panels": "1.1.2-patch.0", "react-redux": "^7.2.4", + "react-router-dom": "^5.2.0", "redux": "^4.1.0", "revolt.js": "4.2.0-alpha.3-patch.0", "rimraf": "^3.0.2", diff --git a/src/app.tsx b/src/app.tsx index b040b2e6..f0f1f387 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,19 +1,22 @@ -import { Text } from "preact-i18n"; +import { CheckAuth } from "./context/revoltjs/CheckAuth"; +import { Route, Switch } from "react-router-dom"; import Context from "./context"; -import dayjs from "dayjs"; - -import localeData from "dayjs/plugin/localeData"; -dayjs.extend(localeData); - export function App() { return ( -

- -

-

{dayjs.locale()}

-

{dayjs.months()}

+ + + +

login

+
+
+ + +

revolt app

+
+
+
); } diff --git a/src/context/index.tsx b/src/context/index.tsx index 95219c43..cf025690 100644 --- a/src/context/index.tsx +++ b/src/context/index.tsx @@ -1,15 +1,21 @@ import State from "../redux/State"; import { Children } from "../types/Preact"; +import { BrowserRouter } from "react-router-dom"; +import ClientContext from './revoltjs/RevoltClient'; import Locale from "./Locale"; import Theme from "./Theme"; export default function Context({ children }: { children: Children }) { return ( - - - {children} - - + + + + + {children} + + + + ); } diff --git a/src/context/revoltjs/CheckAuth.tsx b/src/context/revoltjs/CheckAuth.tsx new file mode 100644 index 00000000..3933e913 --- /dev/null +++ b/src/context/revoltjs/CheckAuth.tsx @@ -0,0 +1,22 @@ +import { ReactNode } from "react"; +import { useContext } from "preact/hooks"; +import { Redirect } from "react-router-dom"; + +import { AppContext } from "./RevoltClient"; + +interface Props { + auth?: boolean; + children: ReactNode | ReactNode[]; +} + +export const CheckAuth = (props: Props) => { + const { operations } = useContext(AppContext); + + if (props.auth && !operations.ready()) { + return ; + } else if (!props.auth && operations.ready()) { + return ; + } + + return <>{props.children}; +}; diff --git a/src/context/revoltjs/RevoltClient.tsx b/src/context/revoltjs/RevoltClient.tsx index 737f2824..a6067306 100644 --- a/src/context/revoltjs/RevoltClient.tsx +++ b/src/context/revoltjs/RevoltClient.tsx @@ -1,4 +1,12 @@ import { Client } from "revolt.js"; +import { createContext } from "preact"; +import { useState } from "preact/hooks"; +import { Children } from "../../types/Preact"; +import { Route } from "revolt.js/dist/api/routes"; +import { connectState } from "../../redux/connector"; +import { WithDispatcher } from "../../redux/reducers"; +import { AuthState } from "../../redux/reducers/auth"; +import { SyncOptions } from "../../redux/reducers/sync"; export enum ClientStatus { LOADING, @@ -10,10 +18,60 @@ export enum ClientStatus { ONLINE, } -export const RevoltJSClient = new Client({ +export interface ClientOperations { + login: (data: Route<"POST", "/auth/login">["data"]) => Promise; + logout: (shouldRequest?: boolean) => Promise; + loggedIn: () => boolean; + ready: () => boolean; +} + +export interface AppState { + status: ClientStatus; + operations: ClientOperations; +} + +export const AppContext = createContext(undefined as any); + +export const RevoltClient = new Client({ autoReconnect: false, - apiURL: process.env.API_SERVER, + apiURL: import.meta.env.VITE_API_URL, debug: process.env.NODE_ENV === "development", - // Match sw.js#13 // db: new Db("state", 3, ["channels", "servers", "users", "members"]) }); + +type Props = WithDispatcher & { + auth: AuthState; + sync: SyncOptions; + children: Children; +}; + +function Context({ auth, sync, children, dispatcher }: Props) { + const [status, setStatus] = useState(ClientStatus.LOADING); + + const value: AppState = { + status, + operations: { + login: async data => {}, + logout: async shouldRequest => {}, + loggedIn: () => false, + ready: () => false + } + }; + + return ( + + { children } + + ); +} + +export default connectState<{ children: Children }>( + Context, + state => { + return { + auth: state.auth, + sync: state.sync + }; + }, + true +); diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 00000000..2f894b5f --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,5 @@ +interface ImportMetaEnv { + VITE_API_URL: string; + VITE_THEMES_URL: string; +} + \ No newline at end of file diff --git a/src/redux/State.tsx b/src/redux/State.tsx index 5095fcdc..c7f8575d 100644 --- a/src/redux/State.tsx +++ b/src/redux/State.tsx @@ -4,13 +4,6 @@ import { Provider } from "react-redux"; import { Children } from "../types/Preact"; import { useEffect, useState } from "preact/hooks"; -async function loadState() { - const state = await localForage.getItem("state"); - if (state) { - store.dispatch({ type: "__INIT", state }); - } -} - interface Props { children: Children; } @@ -19,10 +12,16 @@ export default function State(props: Props) { const [loaded, setLoaded] = useState(false); useEffect(() => { - loadState().then(() => setLoaded(true)); + localForage.getItem("state") + .then(state => { + if (state !== null) { + store.dispatch({ type: "__INIT", state }); + } + + setLoaded(true); + }); }, []); if (!loaded) return null; - return {props.children}; } diff --git a/src/redux/index.ts b/src/redux/index.ts index 6d78cc51..a8e2270f 100644 --- a/src/redux/index.ts +++ b/src/redux/index.ts @@ -2,6 +2,7 @@ import { createStore } from "redux"; import rootReducer from "./reducers"; import localForage from "localforage"; +import { Core } from "revolt.js/dist/api/objects"; import { Typing } from "./reducers/typing"; import { Drafts } from "./reducers/drafts"; import { AuthState } from "./reducers/auth"; @@ -13,6 +14,7 @@ import { QueuedMessage } from "./reducers/queue"; import { ExperimentOptions } from "./reducers/experiments"; export type State = { + config: Core.RevoltNodeConfiguration, locale: Language; auth: AuthState; settings: Settings; @@ -40,6 +42,7 @@ export const store = createStore((state: any, action: any) => { // Save state using localForage. store.subscribe(() => { const { + config, locale, auth, settings, @@ -51,6 +54,7 @@ store.subscribe(() => { } = store.getState() as State; localForage.setItem("state", { + config, locale, auth, settings, diff --git a/src/redux/reducers/index.ts b/src/redux/reducers/index.ts index 3c8d83c9..a5e81c65 100644 --- a/src/redux/reducers/index.ts +++ b/src/redux/reducers/index.ts @@ -1,6 +1,7 @@ import { State } from ".."; import { combineReducers } from "redux"; +import { config, ConfigAction } from "./server_config"; import { settings, SettingsAction } from "./settings"; import { locale, LocaleAction } from "./locale"; import { auth, AuthAction } from "./auth"; @@ -12,6 +13,7 @@ import { sync, SyncAction } from "./sync"; import { experiments, ExperimentsAction } from "./experiments"; export default combineReducers({ + config, locale, auth, settings, @@ -24,6 +26,7 @@ export default combineReducers({ }); export type Action = + | ConfigAction | LocaleAction | AuthAction | SettingsAction diff --git a/src/redux/reducers/server_config.ts b/src/redux/reducers/server_config.ts new file mode 100644 index 00000000..9e14fb0b --- /dev/null +++ b/src/redux/reducers/server_config.ts @@ -0,0 +1,20 @@ +import { Core } from "revolt.js/dist/api/objects"; + +export type ConfigAction = + | { type: undefined } + | { + type: "SET_CONFIG"; + config: Core.RevoltNodeConfiguration; + }; + +export function config( + state = { } as Core.RevoltNodeConfiguration, + action: ConfigAction +): Core.RevoltNodeConfiguration { + switch (action.type) { + case "SET_CONFIG": + return action.config; + default: + return state; + } +} diff --git a/yarn.lock b/yarn.lock index b78df3cc..52f24991 100644 --- a/yarn.lock +++ b/yarn.lock @@ -836,7 +836,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.14.0", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.14.0", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.14.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== @@ -1121,6 +1121,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/history@*": + version "4.7.8" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" + integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== + "@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" @@ -1168,6 +1173,23 @@ hoist-non-react-statics "^3.3.0" redux "^4.0.0" +"@types/react-router-dom@^5.1.7": + version "5.1.7" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.7.tgz#a126d9ea76079ffbbdb0d9225073eb5797ab7271" + integrity sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg== + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*": + version "5.1.15" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.15.tgz#c1069e0da4617fd315e381b56b18b89490e14e2a" + integrity sha512-z3UlMG/x91SFEVmmvykk9FLTliDvfdIUky4k2rCfXWQ0NKbrP8o9BTCaCTPuYsB8gDkUnUmkcA2vYlm2DR+HAA== + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react@*": version "17.0.11" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" @@ -2303,7 +2325,19 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: +history@^4.9.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" + integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^3.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^1.0.1" + +hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -2473,6 +2507,11 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2633,7 +2672,7 @@ lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loose-envify@^1.4.0: +loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -2698,6 +2737,14 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.2.3" +mini-create-react-context@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e" + integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ== + dependencies: + "@babel/runtime" "^7.12.1" + tiny-warning "^1.0.3" + minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -2878,6 +2925,13 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -2947,7 +3001,7 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prop-types@^15.7.2: +prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -3007,7 +3061,7 @@ react-helmet@^6.1.0: react-fast-compare "^3.1.1" react-side-effect "^2.1.0" -react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -3029,6 +3083,35 @@ react-redux@^7.2.4: prop-types "^15.7.2" react-is "^16.13.1" +react-router-dom@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" + integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.2.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" + integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.4.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + react-side-effect@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.1.tgz#66c5701c3e7560ab4822a4ee2742dee215d72eb3" @@ -3119,6 +3202,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-pathname@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== + resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" @@ -3491,6 +3579,16 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" +tiny-invariant@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" + integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + +tiny-warning@^1.0.0, tiny-warning@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -3637,6 +3735,11 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +value-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" + integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== + vite-plugin-pwa@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/vite-plugin-pwa/-/vite-plugin-pwa-0.8.1.tgz#8b6fc6c26fcc6fab9d39a087256ba6280173b6eb"