From bead79590f63125689ca0168f20618c22469ecd0 Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Tue, 3 Sep 2024 12:51:40 -0500 Subject: [PATCH 1/6] Add get key method and expose underlying client --- packages/openapi-react-query/src/index.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/openapi-react-query/src/index.ts b/packages/openapi-react-query/src/index.ts index 438c7aa94..c50b93396 100644 --- a/packages/openapi-react-query/src/index.ts +++ b/packages/openapi-react-query/src/index.ts @@ -54,7 +54,19 @@ export type UseMutationMethod UseMutationResult; +export type GetKeyMethod> = Record>> = < + Method extends HttpMethod, + Path extends PathsWithMethod, + Init extends MaybeOptionalInit, +>( + method: Method, + url: Path, + init?: Init, +) => [Method, Path, Init | undefined]; + export interface OpenapiQueryClient { + client: FetchClient; + getKey: GetKeyMethod; useQuery: UseQueryMethod; useSuspenseQuery: UseSuspenseQueryMethod; useMutation: UseMutationMethod; @@ -66,6 +78,8 @@ export default function createClient, ): OpenapiQueryClient { return { + client, + getKey: (method, path, init) => [method, path, init], useQuery: (method, path, ...[init, options, queryClient]) => { return useQuery( { From cef9ed5894653f3549f821eb82a0ea6db3cf56c3 Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Tue, 3 Sep 2024 14:29:50 -0500 Subject: [PATCH 2/6] Added doc --- docs/openapi-react-query/get-key.md | 64 +++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 docs/openapi-react-query/get-key.md diff --git a/docs/openapi-react-query/get-key.md b/docs/openapi-react-query/get-key.md new file mode 100644 index 000000000..5e2349850 --- /dev/null +++ b/docs/openapi-react-query/get-key.md @@ -0,0 +1,64 @@ +--- +title: getKey +--- +# {{ $frontmatter.title }} + +The `getKey` method allows you to generate a cache key consistent with the `useQuery` and `useMutation` methods. This method is useful if you need to invalidate a key in the `queryClient`. + +::: tip +You can find more about this pattern in the [Invalidation from Mutations](https://tanstack.com/query/latest/docs/framework/react/guides/invalidations-from-mutations) section of react-query. +::: + +## Example + +::: code-group + +```tsx [src/app.tsx] +import { $api } from "./api"; + +export const App = () => { + const { mutate } = $api.useMutation("delete", "/users", { + onSuccess: () => { + const queryKey = $api.getKey("get", "/count-users"); + $api.client.invalidateQueries({ queryKey }); + }, + }); + + return ( + + ); +}; +``` + +```ts [src/api.ts] +import createFetchClient from "openapi-fetch"; +import createClient from "openapi-react-query"; +import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript + +const fetchClient = createFetchClient({ + baseUrl: "https://myapi.dev/v1/", +}); +export const $api = createClient(fetchClient); +``` + +::: + +## Api + +```tsx +const queryKey = $api.getKey(method, path, init); +``` + +**Arguments** + +- `method` **(required)** + - The HTTP method to use for the request. + - The method is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information. +- `path` **(required)** + - The pathname to use for the request. + - Must be an available path for the given method in your schema. + - The pathname is used as key. See [Query Keys](https://tanstack.com/query/latest/docs/framework/react/guides/query-keys) for more information. +- `init` + - The fetch options to use for the request. \ No newline at end of file From 2d3a2bfb8044654ed80f99270942cb17ee03d5df Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Tue, 3 Sep 2024 14:49:48 -0500 Subject: [PATCH 3/6] Added test --- .../openapi-react-query/test/index.test.tsx | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/packages/openapi-react-query/test/index.test.tsx b/packages/openapi-react-query/test/index.test.tsx index 64a9a81e1..dd61028be 100644 --- a/packages/openapi-react-query/test/index.test.tsx +++ b/packages/openapi-react-query/test/index.test.tsx @@ -451,4 +451,53 @@ describe("client", () => { }); }); }); + + describe("getKey", () => { + it("should return correct key", () => { + const fetchClient = createFetchClient({ baseUrl }); + const client = createClient(fetchClient); + + const key = client.getKey("get", "/string-array", {}); + + expect(key).toEqual(["get", "/string-array", {}]); + }); + + it("should invalidate query", async () => { + const fetchClient = createFetchClient({ baseUrl }); + const client = createClient(fetchClient); + + useMockRequestHandler({ + baseUrl, + method: "get", + path: "/string-array", + status: 200, + body: ["one", "two", "three"], + }); + + const { result } = renderHook(() => client.useQuery("get", "/string-array"), { + wrapper, + }); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + const { data, error } = result.current; + + expect(data).toBeDefined(); + data && expect(data[0]).toBe("one"); + expect(error).toBeNull(); + + const queryKey = client.getKey("get", "/string-array"); + console.log({ + key: [queryKey], + keys: queryClient.getQueryCache().getAll().map(p => p.queryKey) + }); + + expect(queryClient.getQueryCache().getAll().map(p => p.queryKey)).toEqual([queryKey]); + + // Remove query + await queryClient.removeQueries({ queryKey: queryKey }); + + expect(queryClient.getQueryCache().getAll().map(p => p.queryKey)).not.toEqual([queryKey]); + }); + }); }); From e78078ddcb8d9e3a724e68520b4c150e67edb34a Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Tue, 3 Sep 2024 14:51:04 -0500 Subject: [PATCH 4/6] Fix format --- packages/openapi-react-query/src/index.ts | 4 +++- .../openapi-react-query/test/index.test.tsx | 21 +++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/openapi-react-query/src/index.ts b/packages/openapi-react-query/src/index.ts index c50b93396..02a59abb7 100644 --- a/packages/openapi-react-query/src/index.ts +++ b/packages/openapi-react-query/src/index.ts @@ -54,7 +54,9 @@ export type UseMutationMethod UseMutationResult; -export type GetKeyMethod> = Record>> = < +export type GetKeyMethod< + Paths extends Record> = Record>, +> = < Method extends HttpMethod, Path extends PathsWithMethod, Init extends MaybeOptionalInit, diff --git a/packages/openapi-react-query/test/index.test.tsx b/packages/openapi-react-query/test/index.test.tsx index dd61028be..8cbe66f0f 100644 --- a/packages/openapi-react-query/test/index.test.tsx +++ b/packages/openapi-react-query/test/index.test.tsx @@ -488,16 +488,29 @@ describe("client", () => { const queryKey = client.getKey("get", "/string-array"); console.log({ - key: [queryKey], - keys: queryClient.getQueryCache().getAll().map(p => p.queryKey) + key: [queryKey], + keys: queryClient + .getQueryCache() + .getAll() + .map((p) => p.queryKey), }); - expect(queryClient.getQueryCache().getAll().map(p => p.queryKey)).toEqual([queryKey]); + expect( + queryClient + .getQueryCache() + .getAll() + .map((p) => p.queryKey), + ).toEqual([queryKey]); // Remove query await queryClient.removeQueries({ queryKey: queryKey }); - expect(queryClient.getQueryCache().getAll().map(p => p.queryKey)).not.toEqual([queryKey]); + expect( + queryClient + .getQueryCache() + .getAll() + .map((p) => p.queryKey), + ).not.toEqual([queryKey]); }); }); }); From 2ff475598811f9dad0d33bd3f11dadcf2b34a9b3 Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Tue, 3 Sep 2024 14:53:00 -0500 Subject: [PATCH 5/6] Removed debugging console log --- packages/openapi-react-query/test/index.test.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/openapi-react-query/test/index.test.tsx b/packages/openapi-react-query/test/index.test.tsx index 8cbe66f0f..98e305020 100644 --- a/packages/openapi-react-query/test/index.test.tsx +++ b/packages/openapi-react-query/test/index.test.tsx @@ -487,13 +487,6 @@ describe("client", () => { expect(error).toBeNull(); const queryKey = client.getKey("get", "/string-array"); - console.log({ - key: [queryKey], - keys: queryClient - .getQueryCache() - .getAll() - .map((p) => p.queryKey), - }); expect( queryClient From a0b55a43df051b05b6023c1a4591dc1a78bdd981 Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Tue, 3 Sep 2024 15:13:33 -0500 Subject: [PATCH 6/6] Removed query client --- docs/openapi-react-query/get-key.md | 2 +- packages/openapi-react-query/src/index.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/openapi-react-query/get-key.md b/docs/openapi-react-query/get-key.md index 5e2349850..47b626f80 100644 --- a/docs/openapi-react-query/get-key.md +++ b/docs/openapi-react-query/get-key.md @@ -20,7 +20,7 @@ export const App = () => { const { mutate } = $api.useMutation("delete", "/users", { onSuccess: () => { const queryKey = $api.getKey("get", "/count-users"); - $api.client.invalidateQueries({ queryKey }); + queryClient.invalidateQueries({ queryKey }); }, }); diff --git a/packages/openapi-react-query/src/index.ts b/packages/openapi-react-query/src/index.ts index 02a59abb7..da8d29015 100644 --- a/packages/openapi-react-query/src/index.ts +++ b/packages/openapi-react-query/src/index.ts @@ -67,7 +67,6 @@ export type GetKeyMethod< ) => [Method, Path, Init | undefined]; export interface OpenapiQueryClient { - client: FetchClient; getKey: GetKeyMethod; useQuery: UseQueryMethod; useSuspenseQuery: UseSuspenseQueryMethod; @@ -80,7 +79,6 @@ export default function createClient, ): OpenapiQueryClient { return { - client, getKey: (method, path, init) => [method, path, init], useQuery: (method, path, ...[init, options, queryClient]) => { return useQuery(