Skip to content

Commit 1c66d88

Browse files
committed
feat(valibot): single schema per request
1 parent df03745 commit 1c66d88

File tree

18 files changed

+2038
-1399
lines changed

18 files changed

+2038
-1399
lines changed

.changeset/dry-suits-destroy.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
'@hey-api/openapi-ts': minor
3+
---
4+
5+
feat(valibot): generate a single schema for requests
6+
7+
### Single Valibot schema per request
8+
9+
Previously, we generated a separate schema for each endpoint parameter and request body. In v0.76.0, a single request schema is generated for the whole endpoint. It may contain a request body, parameters, and headers.
10+
11+
```ts
12+
const vData = v.object({
13+
body: v.optional(v.object({
14+
foo: v.optional(v.string()),
15+
bar: v.optional(v.union([v.number(), v.null()])),
16+
})),
17+
headers: v.optional(v.never()),
18+
path: v.object({
19+
baz: v.string(),
20+
}),
21+
query: v.optional(v.never()),
22+
});
23+
```
24+
25+
If you need to access individual fields, you can do so using the [`.entries`](https://valibot.dev/api/object/) API. For example, we can get the request body schema with `vData.entries.body`.

.changeset/six-birds-peel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix(valibot): add `metadata` option to generate additional metadata for documentation, code generation, AI structured outputs, form validation, and other purposes

docs/openapi-ts/migrating.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,30 @@ This config option is deprecated and will be removed in favor of [clients](./cli
2727

2828
This config option is deprecated and will be removed.
2929

30+
## v0.76.0
31+
32+
### Single Valibot schema per request
33+
34+
Previously, we generated a separate schema for each endpoint parameter and request body. In v0.76.0, a single request schema is generated for the whole endpoint. It may contain a request body, parameters, and headers.
35+
36+
```ts
37+
const vData = v.object({
38+
body: v.optional(
39+
v.object({
40+
foo: v.optional(v.string()),
41+
bar: v.optional(v.union([v.number(), v.null()])),
42+
}),
43+
),
44+
headers: v.optional(v.never()),
45+
path: v.object({
46+
baz: v.string(),
47+
}),
48+
query: v.optional(v.never()),
49+
});
50+
```
51+
52+
If you need to access individual fields, you can do so using the [`.entries`](https://valibot.dev/api/object/) API. For example, we can get the request body schema with `vData.entries.body`.
53+
3054
## v0.75.0
3155

3256
### Updated TanStack Query options

docs/openapi-ts/plugins/valibot.md

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,18 @@ Launch demo
2626
## Features
2727

2828
- seamless integration with `@hey-api/openapi-ts` ecosystem
29-
- Valibot schemas for request payloads, parameters, and responses
29+
- Valibot schemas for requests, responses, and reusable definitions
3030

3131
## Installation
3232

3333
In your [configuration](/openapi-ts/get-started), add `valibot` to your plugins and you'll be ready to generate Valibot artifacts. :tada:
3434

3535
```js
36-
import { defaultPlugins } from '@hey-api/openapi-ts';
37-
3836
export default {
3937
input: 'https://get.heyapi.dev/hey-api/backend',
4038
output: 'src/client',
4139
plugins: [
42-
...defaultPlugins,
40+
// ...other plugins
4341
'valibot', // [!code ++]
4442
],
4543
};
@@ -50,13 +48,11 @@ export default {
5048
To automatically validate response data in your SDKs, set `sdk.validator` to `true`.
5149

5250
```js
53-
import { defaultPlugins } from '@hey-api/openapi-ts';
54-
5551
export default {
5652
input: 'https://get.heyapi.dev/hey-api/backend',
5753
output: 'src/client',
5854
plugins: [
59-
...defaultPlugins,
55+
// ...other plugins
6056
'valibot',
6157
{
6258
name: '@hey-api/sdk', // [!code ++]
@@ -70,6 +66,32 @@ export default {
7066

7167
The Valibot plugin will generate the following artifacts, depending on the input specification.
7268

69+
## Requests
70+
71+
A single request schema is generated for each endpoint. It may contain a request body, parameters, and headers.
72+
73+
```ts
74+
const vData = v.object({
75+
body: v.optional(
76+
v.object({
77+
foo: v.optional(v.string()),
78+
bar: v.optional(v.union([v.number(), v.null()])),
79+
}),
80+
),
81+
headers: v.optional(v.never()),
82+
path: v.object({
83+
baz: v.string(),
84+
}),
85+
query: v.optional(v.never()),
86+
});
87+
```
88+
89+
::: tip
90+
If you need to access individual fields, you can do so using the [`.entries`](https://valibot.dev/api/object/) API. For example, we can get the request body schema with `vData.entries.body`.
91+
:::
92+
93+
You can customize the naming and casing pattern for requests using the `requests.name` and `requests.case` options.
94+
7395
## Responses
7496

7597
A single Valibot schema is generated for all endpoint's responses. If the endpoint describes multiple responses, the generated schema is a union of all possible response shapes.
@@ -85,37 +107,38 @@ const vResponse = v.union([
85107
]);
86108
```
87109

88-
## Request Bodies
89-
90-
If an endpoint describes a request body, we will generate a Valibot schema representing its shape.
110+
You can customize the naming and casing pattern for responses using the `responses.name` and `responses.case` options.
91111

92-
```ts
93-
const vData = v.object({
94-
foo: v.optional(v.string()),
95-
bar: v.optional(v.union([v.number(), v.null()])),
96-
});
97-
```
112+
## Definitions
98113

99-
## Parameters
100-
101-
A separate Valibot schema is generated for every request parameter.
114+
A Valibot schema is generated for every reusable definition from your input.
102115

103116
```ts
104-
const vParameterFoo = v.pipe(v.number(), v.integer());
117+
const vFoo = v.pipe(v.number(), v.integer());
105118

106-
const vParameterBar = v.string();
119+
const vBar = v.object({
120+
bar: v.optional(v.array(v.pipe(v.number(), v.integer()))),
121+
});
107122
```
108123

109-
## Schemas
124+
You can customize the naming and casing pattern for definitions using the `definitions.name` and `definitions.case` options.
110125

111-
A separate Valibot schema is generated for every reusable schema.
126+
## Metadata
112127

113-
```ts
114-
const vFoo = v.pipe(v.number(), v.integer());
128+
It's often useful to associate a schema with some additional [metadata](https://valibot.dev/api/metadata/) for documentation, code generation, AI structured outputs, form validation, and other purposes. If this is your use case, you can set `metadata` to `true` to generate additional metadata about schemas.
115129

116-
const vBar = v.object({
117-
bar: v.optional(v.union([v.array(v.unknown()), v.null()])),
118-
});
130+
```js
131+
export default {
132+
input: 'https://get.heyapi.dev/hey-api/backend',
133+
output: 'src/client',
134+
plugins: [
135+
// ...other plugins
136+
{
137+
metadata: true, // [!code ++]
138+
name: 'valibot',
139+
},
140+
],
141+
};
119142
```
120143

121144
<!--@include: ../../examples.md-->

packages/openapi-ts-tests/test/3.1.x.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,10 @@ describe(`OpenAPI ${version}`, () => {
734734
input: 'validators.yaml',
735735
output: 'validators-metadata',
736736
plugins: [
737-
'valibot',
737+
{
738+
metadata: true,
739+
name: 'valibot',
740+
},
738741
{
739742
metadata: true,
740743
name: 'zod',

packages/openapi-ts-tests/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-valibot/valibot.gen.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ export const vBar = v.object({
1212
foo: v.pipe(v.number(), v.integer())
1313
});
1414

15+
export const vPostFooData = v.object({
16+
body: v.optional(v.never()),
17+
headers: v.optional(v.never()),
18+
path: v.optional(v.never()),
19+
query: v.optional(v.never())
20+
});
21+
1522
/**
1623
* OK
1724
*/

0 commit comments

Comments
 (0)