diff --git a/.pnp.cjs b/.pnp.cjs index 0d52ef1..e24a9ea 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -2612,6 +2612,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "HARD"\ }],\ + ["npm:18.11.9", {\ + "packageLocation": "./.yarn/cache/@types-node-npm-18.11.9-d21dd6ec05-cc0aae109e.zip/node_modules/@types/node/",\ + "packageDependencies": [\ + ["@types/node", "npm:18.11.9"]\ + ],\ + "linkType": "HARD"\ + }],\ ["npm:18.8.2", {\ "packageLocation": "./.yarn/cache/@types-node-npm-18.8.2-3df86443f1-b7c74dea0e.zip/node_modules/@types/node/",\ "packageDependencies": [\ @@ -4321,6 +4328,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["ieee754", "npm:1.2.1"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:6.0.3", {\ + "packageLocation": "./.yarn/cache/buffer-npm-6.0.3-cd90dfedfe-5ad23293d9.zip/node_modules/buffer/",\ + "packageDependencies": [\ + ["buffer", "npm:6.0.3"],\ + ["base64-js", "npm:1.5.1"],\ + ["ieee754", "npm:1.2.1"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["buffer-from", [\ @@ -5840,9 +5856,11 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["example", "workspace:packages/example"],\ ["@playwright/test", "npm:1.27.1"],\ + ["@types/node", "npm:18.11.9"],\ ["@types/react", "npm:18.0.21"],\ ["@types/react-dom", "npm:18.0.6"],\ ["@vitejs/plugin-react", "virtual:0f582dce106adea8a36c1b47cdf139a9f3b829e6f9f0e7abe55d280edb02ebeb0346b97ace0f022e744e8d1d612628f6a3678aa1f9693c8d73c63fcb9908fd80#npm:2.1.0"],\ + ["buffer", "npm:6.0.3"],\ ["msw", "virtual:0f582dce106adea8a36c1b47cdf139a9f3b829e6f9f0e7abe55d280edb02ebeb0346b97ace0f022e744e8d1d612628f6a3678aa1f9693c8d73c63fcb9908fd80#npm:0.47.4"],\ ["playwright-msw", "virtual:0f582dce106adea8a36c1b47cdf139a9f3b829e6f9f0e7abe55d280edb02ebeb0346b97ace0f022e744e8d1d612628f6a3678aa1f9693c8d73c63fcb9908fd80#workspace:packages/playwright-msw"],\ ["react", "npm:18.2.0"],\ diff --git a/.yarn/cache/@types-node-npm-18.11.9-d21dd6ec05-cc0aae109e.zip b/.yarn/cache/@types-node-npm-18.11.9-d21dd6ec05-cc0aae109e.zip new file mode 100644 index 0000000..341a77a Binary files /dev/null and b/.yarn/cache/@types-node-npm-18.11.9-d21dd6ec05-cc0aae109e.zip differ diff --git a/.yarn/cache/buffer-npm-6.0.3-cd90dfedfe-5ad23293d9.zip b/.yarn/cache/buffer-npm-6.0.3-cd90dfedfe-5ad23293d9.zip new file mode 100644 index 0000000..dbf2748 Binary files /dev/null and b/.yarn/cache/buffer-npm-6.0.3-cd90dfedfe-5ad23293d9.zip differ diff --git a/packages/example/package.json b/packages/example/package.json index 5b5acb8..96ed599 100755 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -10,6 +10,7 @@ "test:report": "yarn playwright show-report tests/playwright/report" }, "dependencies": { + "buffer": "^6.0.3", "msw": "0.47.4", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -18,6 +19,7 @@ }, "devDependencies": { "@playwright/test": "^1.27.1", + "@types/node": "^18.11.9", "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", "@vitejs/plugin-react": "^2.1.0", diff --git a/packages/example/src/components/login-form.tsx b/packages/example/src/components/login-form.tsx index 63babcb..b3d741f 100644 --- a/packages/example/src/components/login-form.tsx +++ b/packages/example/src/components/login-form.tsx @@ -1,6 +1,10 @@ import { FC, FormEvent, useCallback } from "react"; -import { useMutation } from "react-query"; -import { LoginApiResponse, LoginApiRequestBody } from "../types/api"; +import { useMutation, useQuery } from "react-query"; +import { + GetSessionResponse, + PostSessionResponse, + PostSessionRequestBody, +} from "../types/session"; const getLoginFormValues = ({ elements }: HTMLFormElement) => { const usernameElement = elements.namedItem("username") as HTMLInputElement; @@ -20,15 +24,29 @@ const getLoginErrorMessage = ({ status }: Response) => { } }; +const useSessionQuery = () => { + return useQuery<{ status: number; session: GetSessionResponse | null }>( + ["session"], + async () => { + const response = await fetch("/api/session"); + return { + status: response.status, + session: response.status === 200 ? await response.json() : null, + }; + }, + { retry: false, refetchOnWindowFocus: false, refetchOnMount: false } + ); +}; + const useLoginMutation = () => { return useMutation< - LoginApiResponse, + PostSessionResponse, { message: string }, - LoginApiRequestBody + PostSessionRequestBody >( ["login"], async (credentials: { username: string; password: string }) => { - const response = await fetch("/api/login", { + const response = await fetch("/api/session", { method: "POST", body: JSON.stringify(credentials), }); @@ -43,46 +61,94 @@ const useLoginMutation = () => { ); }; +const useLogoutMutation = () => { + return useMutation( + ["login"], + async () => { + const response = await fetch("/api/session", { + method: "DELETE", + }); + + if (response.status !== 200) { + throw new Error("Failed to logout"); + } + }, + { retry: false } + ); +}; + export const LoginForm: FC = () => { + const sessionQuery = useSessionQuery(); const loginMutation = useLoginMutation(); - + const logoutMutation = useLogoutMutation(); const handleFormSubmit = useCallback( (event: FormEvent) => { event.preventDefault(); - loginMutation.mutate(getLoginFormValues(event.target as HTMLFormElement)); + loginMutation.mutate( + getLoginFormValues(event.target as HTMLFormElement), + { + onSuccess: () => { + sessionQuery.refetch(); + }, + } + ); }, [loginMutation.mutate] ); - if (loginMutation.isSuccess) { - return