-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
3,114 additions
and
417 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@workleap/create-schemas": minor | ||
--- | ||
|
||
Add new load hook for Plugins |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@workleap/create-schemas": minor | ||
--- | ||
|
||
Add new React Client Plugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
--- | ||
icon: <svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.8 3.14c-.26 1.08-.17 2.57.22 4.5.01.07.03.14.06.2-.71.2-1.35.4-1.9.65a5.54 5.54 0 0 0-2.83 2.2 2.5 2.5 0 0 0-.3 1.74c.1.56.41 1.07.88 1.52.78.77 2.08 1.43 3.9 2.05l.24.06c-.2.74-.34 1.43-.42 2.06-.2 1.49-.06 2.7.46 3.6.31.56.76.96 1.31 1.15.53.18 1.11.17 1.73-.02 1.04-.32 2.25-1.13 3.7-2.45l.2-.23c.5.53 1 .99 1.48 1.36 1.16.92 2.25 1.4 3.28 1.4.63 0 1.19-.2 1.63-.6.41-.37.69-.9.84-1.54.25-1.08.17-2.56-.22-4.5a1.15 1.15 0 0 0-.08-.23c.7-.19 1.3-.4 1.85-.63a5.54 5.54 0 0 0 2.82-2.2 2.5 2.5 0 0 0 .3-1.74 2.9 2.9 0 0 0-.88-1.52c-.78-.77-2.08-1.43-3.9-2.05a1.08 1.08 0 0 0-.22-.05c.19-.72.32-1.38.4-1.99.2-1.49.06-2.7-.46-3.6a2.41 2.41 0 0 0-1.31-1.15 2.76 2.76 0 0 0-1.73.02c-1.04.32-2.25 1.13-3.7 2.45-.05.05-.1.1-.13.15-.51-.53-1-.98-1.48-1.35C9.38 1.48 8.3 1 7.26 1c-.62 0-1.18.2-1.62.6-.42.37-.7.9-.84 1.54Zm2.58 10.8v-.02a.34.34 0 0 0-.5-.1c-.06.04-.1.1-.12.16-1.3 3.48-1.57 5.88-.82 7.2.77 1.35 2.43.9 4.99-1.34l.08-.07v-.01a.36.36 0 0 0 .04-.49 36.75 36.75 0 0 1-3.61-5.23l-.06-.1Zm3.05-5.87h2.96a1.19 1.19 0 0 1 1.05.62l1.49 2.65a1.26 1.26 0 0 1 0 1.23l-1.49 2.65a1.22 1.22 0 0 1-1.05.62h-2.96a1.2 1.2 0 0 1-1.04-.62l-1.5-2.65a1.26 1.26 0 0 1 0-1.23l1.5-2.65a1.22 1.22 0 0 1 1.04-.62Zm7.6 8.46a.34.34 0 0 0-.25-.05 34.7 34.7 0 0 1-6.18.55h-.13a.34.34 0 0 0-.3.2.36.36 0 0 0 .04.38c2.29 2.89 4.18 4.33 5.66 4.33 1.51 0 1.96-1.7 1.33-5.08l-.02-.1v-.01a.35.35 0 0 0-.15-.22Zm1.05-7.6.1.03c3.17 1.13 4.37 2.37 3.6 3.71-.74 1.32-2.9 2.28-6.47 2.88a.34.34 0 0 1-.34-.15.36.36 0 0 1-.01-.38 34.78 34.78 0 0 0 2.7-5.88.35.35 0 0 1 .16-.19.34.34 0 0 1 .25-.03Zm-1.84 1.09c1.3-3.48 1.57-5.88.82-7.2-.77-1.35-2.43-.9-4.99 1.34l-.08.07v.01a.36.36 0 0 0-.04.49 36.73 36.73 0 0 1 3.61 5.23l.06.1v.02c.04.06.09.1.15.13a.34.34 0 0 0 .36-.03c.05-.04.1-.1.11-.16Zm-9.98-8c1.48 0 3.37 1.44 5.66 4.33a.36.36 0 0 1-.08.52.34.34 0 0 1-.18.05h-.13a32.42 32.42 0 0 0-6.18.56.34.34 0 0 1-.25-.06.35.35 0 0 1-.15-.21V7.2l-.02-.1c-.63-3.4-.18-5.08 1.33-5.08Zm.76 6.43a.34.34 0 0 0-.33-.14c-3.58.6-5.73 1.57-6.48 2.88-.76 1.35.44 2.59 3.6 3.71l.1.04h.01c.09.03.18.02.26-.02a.35.35 0 0 0 .17-.2 37.22 37.22 0 0 1 2.73-6 .36.36 0 0 0-.06-.27Z"/><path d="M10.43 8.07h2.96a1.19 1.19 0 0 1 1.05.62l1.49 2.65a1.26 1.26 0 0 1 0 1.23l-1.49 2.65a1.22 1.22 0 0 1-1.05.62h-2.96a1.2 1.2 0 0 1-1.04-.62l-1.5-2.65a1.26 1.26 0 0 1 0-1.23l1.5-2.65a1.22 1.22 0 0 1 1.04-.62Z" fill-opacity=".25"/><path d="M7.37 13.92v.01l.07.1a34.5 34.5 0 0 0 3.6 5.24.36.36 0 0 1-.02.49H11l-.08.08c-2.56 2.24-4.22 2.69-5 1.34-.74-1.32-.47-3.72.83-7.2a.35.35 0 0 1 .11-.16.34.34 0 0 1 .5.1Zm10.41 2.56c.09-.02.18 0 .25.05s.13.13.15.22v.01l.02.1c.63 3.39.18 5.08-1.33 5.08-1.48 0-3.37-1.44-5.66-4.33a.36.36 0 0 1 .26-.58h.13a32.4 32.4 0 0 0 6.18-.55Zm1.3-7.55.1.03c3.17 1.13 4.37 2.37 3.6 3.71-.74 1.32-2.9 2.28-6.47 2.88a.34.34 0 0 1-.34-.15.36.36 0 0 1-.01-.38 34.78 34.78 0 0 0 2.7-5.88.35.35 0 0 1 .16-.19.34.34 0 0 1 .25-.03Zm-1.02-6.11c.75 1.32.48 3.72-.82 7.2a.34.34 0 0 1-.62.06v-.01l-.06-.1a34.5 34.5 0 0 0-3.6-5.24.36.36 0 0 1 .02-.49H13l.08-.08c2.56-2.24 4.22-2.69 5-1.34Zm-10.8-.8c1.48 0 3.37 1.44 5.66 4.33a.36.36 0 0 1-.08.52.34.34 0 0 1-.18.05h-.13a32.42 32.42 0 0 0-6.18.56.34.34 0 0 1-.25-.06.35.35 0 0 1-.15-.21V7.2l-.02-.1c-.63-3.4-.18-5.08 1.33-5.08Zm.66 6.34a.35.35 0 0 1 .16.22.36.36 0 0 1-.04.26 34.7 34.7 0 0 0-2.7 5.88.35.35 0 0 1-.16.2.34.34 0 0 1-.26.02l-.1-.04c-3.17-1.12-4.37-2.36-3.6-3.7.74-1.32 2.9-2.28 6.47-2.88.08-.02.16 0 .23.04Z" fill-opacity=".5"/></svg> | ||
label: TanStack React Query | ||
order: -5 | ||
--- | ||
|
||
# TanStack React Query | ||
|
||
|
||
The React Query plugin lets you generate type-safe React Query hooks to fetch data. | ||
|
||
## Usage | ||
|
||
First, add the `reactQueryPlugin` to your configuration: | ||
|
||
```ts #2,5 create-schemas.config.ts | ||
import { defineConfig } from "@workleap/create-schemas"; | ||
import { reactQueryPlugin } from "@workleap/create-schemas/plugins"; | ||
|
||
export default defineConfig({ | ||
plugins: [reactQueryPlugin()] | ||
input: "petstore.yaml", | ||
outdir: "codegen", | ||
}); | ||
``` | ||
|
||
Add the generated provider to the root of your app. You typically want to add the provider next to where you define React Query's `QueryClientProvider`. This provider will be named after your API: | ||
|
||
```tsx #1,4,10,16 src/App.tsx | ||
import { PetStoreAPIClientProvider, OpenAPIClient } from "./codegen/queries.tsx"; | ||
import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; | ||
|
||
const client = new OpenAPIClient({ baseURL: "https://petstore.io/v3" }); | ||
|
||
const queryClient = new QueryClient(); | ||
|
||
export function App() { | ||
return ( | ||
<PetStoreAPIClientProvider client={client}> | ||
<QueryClientProvider client={queryClient}> | ||
<Suspense> | ||
<Home /> | ||
</Suspense> | ||
</QueryClientProvider> | ||
</PetStoreAPIClientProvider> | ||
); | ||
} | ||
|
||
``` | ||
|
||
Then, you can then import the client from the `./queries.tsx` file. The client will be named after the `info.title` property: | ||
|
||
```tsx | ||
import { useListPetsSuspenseQuery } from "./codegen/queries.tsx"; | ||
|
||
export function Home() { | ||
const { data: pets } = useListPetsSuspenseQuery({ query: { limit: 10 }}); | ||
|
||
return ( | ||
<div> | ||
<h1>Pets</h1> | ||
<ul> | ||
{pets.map(pet => <li key={pet.id}>{pet.name}</li>)} | ||
</ul> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
## Hooks | ||
|
||
The `reactQueryPlugin` generates the following functions for each endpoints, where `___` is the name of the endpoint's `operationId`: | ||
|
||
## `use___Query(options)` | ||
|
||
Hook used to fetch data using the `useQuery` hook. | ||
|
||
**Example:** | ||
```tsx | ||
const { data, error, isLoading } = useListPetsQuery(); | ||
|
||
if (error) { | ||
return <div>Something went wrong!</div>; | ||
} else if (isLoading) { | ||
return <div>Loading...</div>; | ||
} else { | ||
return data.map(pet => <li key={pet.id}>{pet.name}</li>); | ||
} | ||
|
||
``` | ||
|
||
## `use___SuspenseQuery(options)` | ||
|
||
Hook used to fetch data using the `useSuspenseQuery` hook. | ||
|
||
Unlike the `useQuery` version, you don't need to check if the data is loading or if there was an error. If execution resumes, the data is guaranteed to be available. This can lead to simplified code. | ||
|
||
If there is an error, the hook will throw to the closest parent error boundary. | ||
|
||
**Example:** | ||
```tsx | ||
const { data } = useListPetsSuspenseQuery(); | ||
|
||
return data.map(pet => <li key={pet.id}>{pet.name}</li>); | ||
``` | ||
|
||
## `use___Mutation(options)` | ||
|
||
!!! | ||
This hook is only generated for the methods `POST`, `PUT`, `PATCH` and `DELETE`. | ||
!!! | ||
|
||
Hook used to mutate data using the `useMutation` hook. | ||
|
||
**Example:** | ||
```tsx | ||
const { mutate, isPending } = useAddPetMutation(); | ||
|
||
function handleClick() { | ||
mutate({ | ||
body: { name: "fido", kind: "dog" }, | ||
request: { signal: AbortSignal.timeout(500) } | ||
}, { | ||
onSuccess: assistant => { | ||
queryClient.invalidateQueries({ queryKey: listPetsQueryKey() }); | ||
} | ||
}); | ||
} | ||
|
||
return <button onClick={handleClick} disabled={isPending}>Add pet</button> | ||
``` | ||
|
||
## `prefetch___(client, queryClient, init)` | ||
|
||
Function used to prefetch data. You typically want to call this in a `loader` function for your route. | ||
|
||
## `___QueryKey(init)` | ||
|
||
Function used to obtain the QueryKey of a specific endpoint. The query key is based on the values passed to the `init` parameter. | ||
|
||
## Middlewares | ||
|
||
You can add logic before or after every requests by using a middleware. You can | ||
add a middleware to the client using the `.addMiddleware(middleware, [options])` method, and you can | ||
remove it using the `.removeMiddleware(middleware)` method or using an abort signal. | ||
|
||
There are three different functions that middlewares can use: | ||
|
||
- `onRequest(request)`: Runs before the client makes a request. Lets you modify the request object before it is sent. | ||
- `onResponse(response)`: Runs after the client receives a response. | ||
- This function will be called on `4xx` and `5xx`. | ||
- `onError(error)`: Runs when the client is unable to complete a request due to the request being aborted or due to a network error. | ||
- This function will be called on `4xx` or `5xx`. | ||
|
||
**Example:** | ||
|
||
```tsx | ||
const client = new OpenAPIClient({ baseURL: "https://petstore.io/v3" }); | ||
|
||
client.addMiddleware({ | ||
onResponse(response) { | ||
if (response.status === 401) { | ||
window.location.replace("/login"); | ||
return new Promise(); | ||
} | ||
} | ||
}); | ||
``` | ||
|
||
**Usage with React:** | ||
|
||
Sometimes, you may want a middleware to use data and functions defined inside of your React application. This can be done by adding a middleware inside the `useEffect` hook: | ||
|
||
```tsx #6-12 | ||
const client = new OpenAPIClient({ baseURL: "https://petstore.io/v3" }); | ||
|
||
function ShowToastsOnNetworkError() { | ||
const toast = useToast(); | ||
|
||
useEffect(() => { | ||
const middleware = { onError: () => toast.error("Something went wrong!") }; | ||
|
||
client.addMiddleware(middleware); | ||
|
||
return () => client.removeMiddleware(middleware); | ||
}, [toast]); | ||
|
||
return null; | ||
} | ||
|
||
function App() { | ||
return ( | ||
<> | ||
<ShowToastsOnNetworkError /> | ||
<Home /> | ||
</> | ||
) | ||
} | ||
``` | ||
|
||
## API | ||
|
||
```ts | ||
interface OpenAPIClientOptions { | ||
baseURL?: string; | ||
query?: SerializeQueryOptions; | ||
headers?: Record<string, string>; | ||
} | ||
|
||
interface Middleware { | ||
onRequest?: (request: Request) => void | Request | Promise<void | Request>; | ||
onResponse?: (response: Response) => void | Response | Promise<void | Response>; | ||
onError?: (error: unknown) => void; | ||
request?: RequestInit; | ||
} | ||
|
||
class OpenAPIClient { | ||
constructor(options?: OpenAPIClientOptions); | ||
addMiddleware(middleware: Middleware, options?: { signal?: AbortSignal }): void; | ||
removeMiddleware(middleware: Middleware): void; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.