Skip to content

Commit 9288824

Browse files
committed
Configure vitepress
1 parent 1294679 commit 9288824

File tree

13 files changed

+2000
-210
lines changed

13 files changed

+2000
-210
lines changed

README.md

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,48 @@
1313
</a>
1414
</p>
1515

16-
## Setup
16+
## Introduction
1717

18-
```sh
19-
npm install swr-openapi swr openapi-fetch
20-
```
21-
22-
Follow [openapi-typescript](https://openapi-ts.dev/) directions to generate TypeScript definitions for each service being used.
23-
24-
Here is an example of types being generated for a service via the command line:
25-
26-
```sh
27-
npx openapi-typescript "https://sandwiches.example/openapi/json" --output ./types/sandwich-schema.ts
28-
```
18+
swr-openapi is a type-safe wrapper around [`swr`](https://swr.vercel.app).
2919

30-
## Basic Usage
20+
It works by using [openapi-fetch](https://openapi-ts.dev/openapi-fetch) and [openapi-typescript](https://openapi-ts.dev/introduction) so you get all the following features:
3121

32-
Initialize an [openapi-fetch](https://openapi-ts.dev/openapi-fetch/) client and create any desired hooks.
22+
- ✅ No typos in URLs or params.
23+
- ✅ All parameters, request bodies, and responses are type-checked and 100% match your schema
24+
- ✅ No manual typing of your API
25+
- ✅ Eliminates `any` types that hide bugs
26+
- ✅ Also eliminates `as` type overrides that can also hide bugs
3327

34-
```ts
35-
// sandwich-api.ts
28+
```tsx [src/my-component.ts]
3629
import createClient from "openapi-fetch";
3730
import { createQueryHook } from "swr-openapi";
38-
import type { paths as SandwichPaths } from "./types/sandwich-schema";
31+
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript
3932

40-
const client = createClient<SandwichPaths>(/* ... */);
33+
const client = createClient<paths>({
34+
baseUrl: "https://myapi.dev/v1/",
35+
});
4136

42-
const useSandwiches = createQueryHook(client, "sandwich-api");
37+
const useQuery = createQueryHook(client, "my-api");
4338

44-
const { data, error, isLoading, isValidating, mutate } = useSandwiches(
45-
"/sandwich/{id}", // <- Fully typed paths!
46-
{
47-
params: {
48-
path: {
49-
id: "123", // <- Fully typed params!
39+
function MyComponent() {
40+
const { data, error, isLoading, isValidating, mutate } = useQuery(
41+
"/blogposts/{post_id}",
42+
{
43+
params: {
44+
path: { post_id: "123" },
5045
},
5146
},
52-
},
53-
);
47+
);
48+
49+
if (isLoading || !data) return "Loading...";
50+
51+
if (error) return `An error occured: ${error.message}`;
52+
53+
return <div>{data.title}</div>;
54+
}
55+
5456
```
5557

5658
## 📓 Docs
5759

58-
[View Docs](https://openapi-ts.dev/swr-openapi)
60+
[View Docs](https://htunnicliff.github.io/swr-openapi)

docs/.vitepress/config.ts

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,60 @@ import { defineConfig } from 'vitepress'
44
export default defineConfig({
55
title: "SWR OpenAPI",
66
description: "Bindings for SWR and OpenAPI schemas",
7+
cleanUrls: true,
78
themeConfig: {
9+
outline: "deep",
810
// https://vitepress.dev/reference/default-theme-config
911
nav: [
10-
{ text: 'Home', link: '/' },
11-
{ text: 'Examples', link: '/markdown-examples' }
12+
{ text: 'Home', link: '/', },
13+
{ text: 'Getting Started', link: '/getting-started' },
14+
{ text: 'API Reference', link: '/api/hook-builders' }
1215
],
13-
1416
sidebar: [
1517
{
16-
text: 'Examples',
18+
text: "Getting Started",
19+
items: [
20+
{text: "Introduction", link: "/getting-started"},
21+
{text: "Setup", link: "/getting-started#setup"},
22+
{text: "Basic Usage", link: "/getting-started#basic-usage"}
23+
],
24+
},
25+
{
26+
text: "API Reference",
27+
base: '/api',
1728
items: [
18-
{ text: 'Markdown Examples', link: '/markdown-examples' },
19-
{ text: 'Runtime API Examples', link: '/api-examples' }
29+
{
30+
text: 'Hook Builders',
31+
link: '/hook-builders'
32+
},
33+
{
34+
text: 'useImmutable',
35+
link: '/use-immutable'
36+
},
37+
{
38+
text: 'useInfinite',
39+
link: '/use-infinite'
40+
},
41+
{
42+
text: 'useMutate',
43+
link: '/use-mutate'
44+
},
45+
{
46+
text: 'useQuery',
47+
link: '/use-query'
48+
},
49+
2050
]
21-
}
51+
},
2252
],
23-
2453
socialLinks: [
25-
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' }
26-
]
54+
{ icon: 'github', link: 'https://github.com/htunnicliff/swr-openapi' }
55+
],
56+
footer: {
57+
message: 'Released under the <a href="https://github.com/htunnicliff/swr-openapi/blob/main/LICENSE">MIT License</a>'
58+
},
59+
search: {
60+
provider: "local",
61+
}
2762
}
2863
})

docs/api-examples.md

Lines changed: 0 additions & 49 deletions
This file was deleted.

docs/api/hook-builders.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
---
2+
title: Hook Builders
3+
---
4+
5+
# {{ $frontmatter.title }}
6+
7+
Hook builders initialize `useQuery`, `useImmutate`, `useInfinite`, and `useMutate`.
8+
9+
Each builder function accepts an instance of a [fetch client](https://openapi-ts.dev/openapi-fetch/api) and a prefix unique to that client.
10+
11+
12+
::: tip
13+
14+
Prefixes ensure that `swr` will avoid caching requests from different APIs when requests happen to match (e.g. `GET /health` for "API A" and `GET /health` for "API B").
15+
16+
:::
17+
18+
```ts
19+
import createClient from "openapi-fetch";
20+
import { isMatch } from "lodash-es";
21+
22+
import {
23+
createQueryHook,
24+
createImmutableHook,
25+
createInfiniteHook,
26+
createMutateHook,
27+
} from "swr-openapi";
28+
29+
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript
30+
31+
const client = createClient<paths>(/* ... */);
32+
const prefix = "my-api";
33+
34+
export const useQuery = createQueryHook(client, prefix);
35+
export const useImmutable = createImmutableHook(client, prefix);
36+
export const useInfinite = createInfiniteHook(client, prefix);
37+
export const useMutate = createMutateHook(
38+
client,
39+
prefix,
40+
isMatch, // Or any comparision function
41+
);
42+
```
43+
44+
## API
45+
46+
### Parameters
47+
48+
Each builder hook accepts the same initial parameters:
49+
50+
- `client`: A [fetch client](https://openapi-ts.dev/openapi-fetch/api).
51+
- `prefix`: A prefix unique to the fetch client.
52+
53+
`createMutateHook` also accepts a third parameter:
54+
55+
- [`compare`](#compare): A function to compare fetch options).
56+
57+
### Returns
58+
59+
- `createQueryHook` &rarr; [`useQuery`](./use-query.md)
60+
- `createImmutableHook` &rarr; [`useImmutable`](./use-immutable.md)
61+
- `createInfiniteHook` &rarr; [`useInfinite`](./use-infinite.md)
62+
- `createMutateHook` &rarr; [`useMutate`](./use-mutate.md)
63+
64+
## `compare`
65+
66+
When calling `createMutateHook`, a function must be provided with the following contract:
67+
68+
```ts
69+
type Compare = (init: any, partialInit: object) => boolean;
70+
```
71+
72+
This function is used to determine whether or not a cached request should be updated when `mutate` is called with fetch options.
73+
74+
My personal recommendation is to use lodash's [`isMatch`][lodash-is-match]:
75+
76+
> Performs a partial deep comparison between object and source to determine if object contains equivalent property values.
77+
78+
```ts
79+
const useMutate = createMutateHook(client, "<unique-key>", isMatch);
80+
81+
const mutate = useMutate();
82+
83+
await mutate([
84+
"/path",
85+
{
86+
params: {
87+
query: {
88+
version: "beta",
89+
},
90+
},
91+
},
92+
]);
93+
94+
// ✅ Would be updated
95+
useQuery("/path", {
96+
params: {
97+
query: {
98+
version: "beta",
99+
},
100+
},
101+
});
102+
103+
// ✅ Would be updated
104+
useQuery("/path", {
105+
params: {
106+
query: {
107+
version: "beta",
108+
other: true,
109+
example: [1, 2, 3],
110+
},
111+
},
112+
});
113+
114+
// ❌ Would not be updated
115+
useQuery("/path", {
116+
params: {
117+
query: {},
118+
},
119+
});
120+
121+
// ❌ Would not be updated
122+
useQuery("/path");
123+
124+
// ❌ Would not be updated
125+
useQuery("/path", {
126+
params: {
127+
query: {
128+
version: "alpha",
129+
},
130+
},
131+
});
132+
133+
// ❌ Would not be updated
134+
useQuery("/path", {
135+
params: {
136+
query: {
137+
different: "items",
138+
},
139+
},
140+
});
141+
```
142+
143+
[lodash-is-match]: https://lodash.com/docs/4.17.15#isMatch

docs/api/use-immutable.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: useImmutable
3+
---
4+
5+
# {{ $frontmatter.title }}
6+
7+
This hook has the same contracts as [`useQuery`](./use-query.md). However, instead of wrapping [`useSWR`][swr-api], it wraps `useSWRImmutable`. This immutable hook [disables automatic revalidations][swr-disable-auto-revalidate] but is otherwise identical to `useSWR`.
8+
9+
```ts
10+
import createClient from "openapi-fetch";
11+
import { createImmutableHook } from "swr-openapi";
12+
import type { paths } from "./my-schema";
13+
14+
const useImmutable = createImmutableHook(client, "my-api");
15+
16+
const { data, error, isLoading, isValidating, mutate } = useImmutable(
17+
path,
18+
init,
19+
config,
20+
);
21+
```
22+
23+
## API
24+
25+
### Parameters
26+
27+
Identical to `useQuery` [parameters](./use-query.md#parameters).
28+
29+
### Returns
30+
31+
Identical to `useQuery` [returns](./use-query.md#returns).
32+
33+
34+
[swr-disable-auto-revalidate]: https://swr.vercel.app/docs/revalidation.en-US#disable-automatic-revalidations
35+
[swr-api]: https://swr.vercel.app/docs/api

0 commit comments

Comments
 (0)