@kubb/plugin-swr 5.2.2 → 5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,81 @@
1
+ # Call operations
2
+
3
+ `@kubb/plugin-swr` generates a typed SWR hook for each operation. `GET` operations get `useSWR` hooks such as `useGetPetById`, and `POST`, `PUT`, `PATCH`, and `DELETE` operations get `useSWRMutation` hooks such as `useCreatePet`. Each hook calls the client function from `@kubb/plugin-fetch` or `@kubb/plugin-axios`.
4
+
5
+ ## Queries
6
+
7
+ A query hook takes the operation's grouped request config (`path`, `query`, `headers`, whichever the operation declares) as its first argument:
8
+
9
+ ```typescript
10
+ import { useGetPetById } from './gen/hooks/useGetPetById'
11
+
12
+ const { data, error, isLoading } = useGetPetById({ path: { petId: 1n } })
13
+ ```
14
+
15
+ The second argument takes `query` (any `SWRConfiguration`), `client` (request config for this call, such as `baseURL`), and the Kubb options `shouldFetch` and `immutable`, covered in [Skip requests until ready](#skip-requests-until-ready) and [Fetch immutable data](#fetch-immutable-data):
16
+
17
+ ```typescript
18
+ import { useGetPetById } from './gen/hooks/useGetPetById'
19
+
20
+ useGetPetById(
21
+ { path: { petId: 1n } },
22
+ {
23
+ query: { refreshInterval: 30_000 },
24
+ client: { baseURL: 'https://api.example.com/v1' },
25
+ },
26
+ )
27
+ ```
28
+
29
+ The exported `queryKey` helper includes the operation URL and request parameters. Pass it to SWR's `mutate` to update or revalidate that entry.
30
+
31
+ ## Mutations
32
+
33
+ A mutation hook takes only an options object. Pass the grouped request config to `trigger(...)`:
34
+
35
+ ```typescript
36
+ import { mutate } from 'swr'
37
+ import { useCreatePet } from './gen/hooks/useCreatePet'
38
+ import { getPetsQueryKey } from './gen/hooks/useGetPets'
39
+
40
+ const { trigger, isMutating } = useCreatePet({
41
+ mutation: { onSuccess: () => mutate(getPetsQueryKey()) },
42
+ })
43
+
44
+ await trigger({ body: { name: 'Fluffy' } })
45
+ ```
46
+
47
+ A `mutationKey` helper is exported next to the hook.
48
+
49
+ ## Errors and transport
50
+
51
+ Each generated hook calls the client function with `throwOnError: true`. A failed request sets SWR's `error`, typed from the error responses in the spec. Set the base URL, authentication, interceptors, serialization, and validation on the client plugin. See the [plugin-fetch](https://kubb.dev/extensions/kubb-labs/plugin-fetch) or [plugin-axios](https://kubb.dev/extensions/kubb-labs/plugin-axios) guide.
52
+
53
+ ## Skip requests until ready
54
+
55
+ Set `shouldFetch: false` to give SWR a `null` key and skip the request. Enable it once the required parameters are available. Mutation hooks accept the same switch, and a `null` key stops `trigger` from firing.
56
+
57
+ ```typescript [usage.ts]
58
+ import { useGetPetById } from './gen/hooks/useGetPetById'
59
+
60
+ export function useSelectedPet(petId: bigint | undefined) {
61
+ return useGetPetById(
62
+ { path: { petId: petId ?? 0n } },
63
+ { shouldFetch: petId != null },
64
+ )
65
+ }
66
+ ```
67
+
68
+ ## Fetch immutable data
69
+
70
+ Set `immutable: true` on a query hook for data that stays unchanged. It sets `revalidateIfStale`, `revalidateOnFocus`, and `revalidateOnReconnect` to `false`.
71
+
72
+ ```typescript [usage.ts]
73
+ import { useGetPetById } from './gen/hooks/useGetPetById'
74
+
75
+ const { data, error } = useGetPetById(
76
+ { path: { petId: 1n } },
77
+ { immutable: true },
78
+ )
79
+ ```
80
+
81
+ Options in `query` override these revalidation defaults.
@@ -0,0 +1,164 @@
1
+ # Options
2
+
3
+ Pass these options to `pluginSwr()`, all of them optional. Shared options link to [Shared plugin options](https://kubb.dev/docs/5.x/reference/plugin-options) for details.
4
+
5
+ ## Options overview
6
+
7
+ | Option | Purpose | Default |
8
+ | ------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
9
+ | [`output`](https://kubb.dev/docs/5.x/reference/plugin-options#output) | Where files are written: `path`, `mode`, `barrel`, `banner`, `footer`. | `{ path: 'hooks', barrel: { type: 'named' } }` |
10
+ | [`group`](https://kubb.dev/docs/5.x/reference/plugin-options#group) | Split output by tag or path: `type`, `name`. | None |
11
+ | [`client`](#client) | Which registered client plugin the hooks call. | Auto-detected |
12
+ | [`query`](#query) | Configure the `useSWR` hooks, or turn them off. | `{ methods: ['GET'], importPath: 'swr' }` |
13
+ | [`queryKey`](#querykey) | Build the SWR key for each query hook. | Built-in `queryKeyTransformer` |
14
+ | [`mutation`](#mutation) | Configure the `useSWRMutation` hooks, or turn them off. | `{ methods: ['POST', 'PUT', 'PATCH', 'DELETE'], importPath: 'swr/mutation' }` |
15
+ | [`mutationKey`](#mutationkey) | Build the SWR key for each mutation hook. | Built-in `mutationKeyTransformer` |
16
+ | [`include`](https://kubb.dev/docs/5.x/reference/plugin-options#include) | Keep only operations that match. | None |
17
+ | [`exclude`](https://kubb.dev/docs/5.x/reference/plugin-options#exclude) | Skip operations that match. | `[]` |
18
+ | [`override`](https://kubb.dev/docs/5.x/reference/plugin-options#override) | Apply different options per pattern. | `[]` |
19
+ | [`resolver`](#resolver) | Customize generated names and file paths. | `resolverSwr` |
20
+ | [`macros`](https://kubb.dev/docs/5.x/reference/plugin-options#macros) | Rewrite AST nodes before printing. | `[]` |
21
+
22
+ ## Option details
23
+
24
+ ### client
25
+
26
+ Selects which registered client plugin the hooks call. A single registered client is auto-detected. Set `client` when several are registered.
27
+
28
+ | | |
29
+ | -------- | -------------------- |
30
+ | Type | `'fetch' \| 'axios'` |
31
+ | Required | `false` |
32
+
33
+ ::field-group
34
+
35
+ :::field{name="'fetch'"}
36
+ Calls the operations generated by [`@kubb/plugin-fetch`](https://kubb.dev/extensions/kubb-labs/plugin-fetch).
37
+ :::
38
+
39
+ :::field{name="'axios'"}
40
+ Calls the operations generated by [`@kubb/plugin-axios`](https://kubb.dev/extensions/kubb-labs/plugin-axios).
41
+ :::
42
+
43
+ ::
44
+
45
+ ### query
46
+
47
+ Configures the generated `useSWR` hooks. Pass an object to change the HTTP methods or import path, or `false` to skip query hook generation.
48
+
49
+ | | |
50
+ | -------- | ----------------------------------------- |
51
+ | Type | `Partial<Query> \| false` |
52
+ | Required | `false` |
53
+ | Default | `{ methods: ['GET'], importPath: 'swr' }` |
54
+
55
+ #### query.methods
56
+
57
+ HTTP methods treated as queries. An operation whose method is in this list generates a `useSWR` hook instead of a mutation.
58
+
59
+ | | |
60
+ | -------- | --------------- |
61
+ | Type | `Array<string>` |
62
+ | Required | `false` |
63
+ | Default | `['GET']` |
64
+
65
+ #### query.importPath
66
+
67
+ Module that `useSWR` is imported from, emitted as `import useSWR from '${importPath}'`. Relative and absolute paths are used as written, with relative paths resolved against the generated file.
68
+
69
+ | | |
70
+ | -------- | -------- |
71
+ | Type | `string` |
72
+ | Required | `false` |
73
+ | Default | `'swr'` |
74
+
75
+ ### queryKey
76
+
77
+ Builds the SWR key for each query hook. The callback receives the operation `node`, the active `casing` and `variant: 'query'` and returns the key array. Strings are copied into the generated code as written, so wrap a string literal in `JSON.stringify(...)`.
78
+
79
+ | | |
80
+ | -------- | ------------------------------------------------------ |
81
+ | Type | `(props: { node, casing, variant }) => Array<unknown>` |
82
+ | Required | `false` |
83
+ | Default | Built-in `queryKeyTransformer` |
84
+
85
+ ```typescript
86
+ queryKey: ({ node, variant }) => [JSON.stringify({ variant, operationId: node.operationId })]
87
+ ```
88
+
89
+ ### mutation
90
+
91
+ Configures the generated `useSWRMutation` hooks. Pass an object to change the HTTP methods or import path, or `false` to skip mutation hook generation.
92
+
93
+ | | |
94
+ | -------- | ----------------------------------------------------------------------------- |
95
+ | Type | `Partial<Mutation> \| false` |
96
+ | Required | `false` |
97
+ | Default | `{ methods: ['POST', 'PUT', 'PATCH', 'DELETE'], importPath: 'swr/mutation' }` |
98
+
99
+ #### mutation.methods
100
+
101
+ HTTP methods treated as mutations. An operation whose method is in this list generates a `useSWRMutation` hook instead of a query.
102
+
103
+ | | |
104
+ | -------- | ------------------------------------ |
105
+ | Type | `Array<string>` |
106
+ | Required | `false` |
107
+ | Default | `['POST', 'PUT', 'PATCH', 'DELETE']` |
108
+
109
+ #### mutation.importPath
110
+
111
+ Module that `useSWRMutation` is imported from, emitted as `import useSWRMutation from '${importPath}'`. Relative and absolute paths are used as written, with relative paths resolved against the generated file.
112
+
113
+ | | |
114
+ | -------- | ---------------- |
115
+ | Type | `string` |
116
+ | Required | `false` |
117
+ | Default | `'swr/mutation'` |
118
+
119
+ ### mutationKey
120
+
121
+ Builds the SWR key for each mutation hook. Like `queryKey`, the callback receives the operation `node`, the active `casing` and `variant: 'mutation'` and returns the key array. Strings are copied into the generated code as written, so wrap a string literal in `JSON.stringify(...)`.
122
+
123
+ | | |
124
+ | -------- | ------------------------------------------------------ |
125
+ | Type | `(props: { node, casing, variant }) => Array<unknown>` |
126
+ | Required | `false` |
127
+ | Default | Built-in `mutationKeyTransformer` |
128
+
129
+ ### resolver
130
+
131
+ Overrides generated file and symbol names. Omitted members keep `resolverSwr`. The shared members (`name`, `file`, `imports`) and the `this` context are described under [`resolver`](https://kubb.dev/docs/5.x/reference/plugin-options#resolver).
132
+
133
+ | | |
134
+ | -------- | ---------------------------- |
135
+ | Type | `ResolverPatch<ResolverSwr>` |
136
+ | Required | `false` |
137
+
138
+ ::code-collapse{name="ResolverSwr patch members"}
139
+
140
+ ```typescript [Partial override]
141
+ type ResolverSwrPatch = {
142
+ name?(name: string): string
143
+ file?: {
144
+ baseName?(params: { name: string; extname: string }): string
145
+ path?(params: { baseName: string; output: Output }): string
146
+ }
147
+ imports?(options: ResolveImportsOptions): Array<ImportNode>
148
+ query?: {
149
+ name?(node: OperationNode): string // → 'useGetPetById'
150
+ optionsName?(node: OperationNode): string // → 'getPetByIdQueryOptions'
151
+ keyName?(node: OperationNode): string // → 'getPetByIdQueryKey'
152
+ keyTypeName?(node: OperationNode): string // → 'GetPetByIdQueryKey'
153
+ clientName?(node: OperationNode): string // → 'getPetById'
154
+ }
155
+ mutation?: {
156
+ name?(node: OperationNode): string // → 'useUpdatePet'
157
+ keyName?(node: OperationNode): string // → 'updatePetMutationKey'
158
+ keyTypeName?(node: OperationNode): string // → 'UpdatePetMutationKey'
159
+ argTypeName?(node: OperationNode): string // → 'UpdatePetMutationArg'
160
+ }
161
+ }
162
+ ```
163
+
164
+ ::
@@ -0,0 +1,39 @@
1
+ # SWR
2
+
3
+ Generates typed SWR hooks from your OpenAPI spec: `useSWR` for reads and `useSWRMutation` for writes.
4
+
5
+ The plugin ships no HTTP client. Each hook calls a function generated by a client plugin.
6
+
7
+ ## Setup
8
+
9
+ - Add `@kubb/plugin-ts` and a client plugin: `@kubb/plugin-fetch` or `@kubb/plugin-axios`.
10
+ - Install SWR v2 or higher in the app that uses the generated code.
11
+ - Configure validation on the client plugin, not here.
12
+
13
+ ## Options worth knowing
14
+
15
+ - `client` picks `fetch` or `axios` when both client plugins are registered. A single client is detected automatically.
16
+ - `query` and `mutation` set which HTTP methods become queries (`GET`) and mutations (`POST`, `PUT`, `PATCH`, `DELETE`), and where SWR is imported from (`swr` and `swr/mutation`). Set either to `false` to skip it.
17
+
18
+ ## Example
19
+
20
+ ```typescript [kubb.config.ts]
21
+ import { defineConfig } from 'kubb/config'
22
+ import { pluginTs } from '@kubb/plugin-ts'
23
+ import { pluginFetch } from '@kubb/plugin-fetch'
24
+ import { pluginSwr } from '@kubb/plugin-swr'
25
+
26
+ export default defineConfig({
27
+ input: './petStore.yaml',
28
+ output: { path: './src/gen' },
29
+ plugins: [
30
+ pluginTs(),
31
+ pluginFetch(),
32
+ pluginSwr(),
33
+ ],
34
+ })
35
+ ```
36
+
37
+ ## See also
38
+
39
+ - [SWR](https://swr.vercel.app)
@@ -0,0 +1,200 @@
1
+ {
2
+ "$schema": "https://kubb.dev/schemas/kubb-extension.json",
3
+ "kind": "plugin",
4
+ "name": "plugin-swr",
5
+ "export": "pluginSwr",
6
+ "displayName": "SWR",
7
+ "description": "Generates typed SWR hooks from your OpenAPI spec, so data fetching stays in sync with the API.",
8
+ "category": "framework",
9
+ "icon": {
10
+ "light": "https://kubb.dev/feature/swr.svg"
11
+ },
12
+ "tags": ["swr", "react", "hooks", "data-fetching", "codegen", "openapi"],
13
+ "docs": "https://kubb.dev/extensions/kubb-labs/plugin-swr",
14
+ "maintainers": [
15
+ {
16
+ "name": "Stijn Van Hulle",
17
+ "github": "stijnvanhulle"
18
+ }
19
+ ],
20
+ "dependencies": ["plugin-ts"],
21
+ "compatibility": {
22
+ "kubb": ">=5.8.3",
23
+ "node": ">=22"
24
+ },
25
+ "role": "consumer",
26
+ "options": [
27
+ {
28
+ "key": "outputPath",
29
+ "path": ["output", "path"],
30
+ "label": "Output Path",
31
+ "description": "Output folder for generated files",
32
+ "type": "text",
33
+ "default": "hooks"
34
+ },
35
+ {
36
+ "key": "barrel",
37
+ "path": ["output", "barrel"],
38
+ "label": "Barrel",
39
+ "description": "How index.ts barrel files are generated",
40
+ "type": "select",
41
+ "default": {
42
+ "type": "named"
43
+ },
44
+ "choices": [
45
+ {
46
+ "label": "named",
47
+ "value": {
48
+ "type": "named"
49
+ }
50
+ },
51
+ {
52
+ "label": "named (nested)",
53
+ "value": {
54
+ "type": "named",
55
+ "nested": true
56
+ }
57
+ },
58
+ {
59
+ "label": "all",
60
+ "value": {
61
+ "type": "all"
62
+ }
63
+ },
64
+ {
65
+ "label": "all (nested)",
66
+ "value": {
67
+ "type": "all",
68
+ "nested": true
69
+ }
70
+ },
71
+ {
72
+ "label": "false (disabled)",
73
+ "value": false
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "key": "outputMode",
79
+ "path": ["output", "mode"],
80
+ "label": "Output Mode",
81
+ "description": "How the plugin consolidates its code into files. File mode writes everything into a single file, so the output path must include a file extension and cannot be grouped.",
82
+ "type": "select",
83
+ "default": "directory",
84
+ "choices": [
85
+ {
86
+ "label": "directory (one file per schema)",
87
+ "value": "directory"
88
+ },
89
+ {
90
+ "label": "file (single file)",
91
+ "value": "file"
92
+ }
93
+ ]
94
+ },
95
+ {
96
+ "key": "client",
97
+ "path": ["client"],
98
+ "label": "Client",
99
+ "description": "HTTP client the generated hooks call. Only needed to disambiguate when both plugin-fetch and plugin-axios are enabled",
100
+ "type": "select",
101
+ "default": null,
102
+ "choices": [
103
+ {
104
+ "label": "auto-detect",
105
+ "value": null
106
+ },
107
+ {
108
+ "label": "fetch",
109
+ "value": "fetch"
110
+ },
111
+ {
112
+ "label": "axios",
113
+ "value": "axios"
114
+ }
115
+ ]
116
+ },
117
+ {
118
+ "key": "group",
119
+ "path": ["group"],
120
+ "label": "Group",
121
+ "description": "Group generated operations by OpenAPI tag or path",
122
+ "type": "select",
123
+ "default": null,
124
+ "choices": [
125
+ {
126
+ "label": "none",
127
+ "value": null
128
+ },
129
+ {
130
+ "label": "by tag",
131
+ "value": {
132
+ "type": "tag"
133
+ }
134
+ },
135
+ {
136
+ "label": "by path",
137
+ "value": {
138
+ "type": "path"
139
+ }
140
+ }
141
+ ]
142
+ },
143
+ {
144
+ "key": "excludeTags",
145
+ "path": ["exclude"],
146
+ "label": "Exclude Tags",
147
+ "description": "Comma-separated OpenAPI tags to exclude from generation",
148
+ "type": "list",
149
+ "item": {
150
+ "type": "tag",
151
+ "pattern": "$item"
152
+ }
153
+ },
154
+ {
155
+ "key": "includeTags",
156
+ "path": ["include"],
157
+ "label": "Include Tags",
158
+ "description": "Comma-separated OpenAPI tags to include. Only operations with these tags are generated",
159
+ "type": "list",
160
+ "item": {
161
+ "type": "tag",
162
+ "pattern": "$item"
163
+ }
164
+ },
165
+ {
166
+ "key": "queryMethods",
167
+ "path": ["query", "methods"],
168
+ "label": "Query Methods",
169
+ "description": "Comma-separated HTTP methods treated as queries (default: GET)",
170
+ "type": "list",
171
+ "default": ["GET"],
172
+ "itemCase": "upper"
173
+ },
174
+ {
175
+ "key": "queryImportPath",
176
+ "path": ["query", "importPath"],
177
+ "label": "Query Import Path",
178
+ "description": "Module specifier the generated query hook imports from",
179
+ "type": "text",
180
+ "default": "swr"
181
+ },
182
+ {
183
+ "key": "mutationMethods",
184
+ "path": ["mutation", "methods"],
185
+ "label": "Mutation Methods",
186
+ "description": "Comma-separated HTTP methods treated as mutations (default: POST, PUT, PATCH, DELETE)",
187
+ "type": "list",
188
+ "default": ["POST", "PUT", "PATCH", "DELETE"],
189
+ "itemCase": "upper"
190
+ },
191
+ {
192
+ "key": "mutationImportPath",
193
+ "path": ["mutation", "importPath"],
194
+ "label": "Mutation Import Path",
195
+ "description": "Module specifier the generated mutation hook imports from",
196
+ "type": "text",
197
+ "default": "swr/mutation"
198
+ }
199
+ ]
200
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/plugin-swr",
3
- "version": "5.2.2",
3
+ "version": "5.2.4",
4
4
  "description": "Generate type-safe SWR hooks with Kubb. Covers useSWR and useSWRMutation with full TypeScript support.",
5
5
  "keywords": [
6
6
  "code-generation",
@@ -15,7 +15,7 @@
15
15
  "use-swr",
16
16
  "use-swr-mutation"
17
17
  ],
18
- "homepage": "https://kubb.dev/plugins/plugin-swr",
18
+ "homepage": "https://kubb.dev/extensions/kubb-labs/plugin-swr",
19
19
  "license": "MIT",
20
20
  "author": "stijnvanhulle",
21
21
  "repository": {
@@ -39,6 +39,8 @@
39
39
  ],
40
40
  "files": [
41
41
  "dist",
42
+ "kubb-extension.json",
43
+ "docs",
42
44
  "!/**/**.test.**",
43
45
  "!/**/__tests__/**",
44
46
  "!/**/__snapshots__/**"
@@ -64,25 +66,26 @@
64
66
  "import": "./dist/index.js",
65
67
  "require": "./dist/index.cjs"
66
68
  },
67
- "./package.json": "./package.json"
69
+ "./package.json": "./package.json",
70
+ "./kubb-extension.json": "./kubb-extension.json"
68
71
  },
69
72
  "publishConfig": {
70
73
  "access": "public",
71
74
  "registry": "https://registry.npmjs.org/"
72
75
  },
73
76
  "dependencies": {
74
- "@kubb/plugin-ts": "^5.0.7"
77
+ "@kubb/plugin-ts": "^5.0.9"
75
78
  },
76
79
  "devDependencies": {
77
80
  "@internals/client": "0.0.0",
78
81
  "@internals/shared": "0.0.0",
79
82
  "@internals/tanstack-query": "0.0.0",
80
83
  "@internals/utils": "0.0.0",
81
- "kubb": "^5.8.0",
84
+ "kubb": "^5.8.3",
82
85
  "swr": "^2.5.1"
83
86
  },
84
87
  "peerDependencies": {
85
- "kubb": "^5.8.0",
88
+ "kubb": "^5.8.3",
86
89
  "swr": "^2.0.0"
87
90
  },
88
91
  "peerDependenciesMeta": {