Skip to content

Commit 5e8f1be

Browse files
authored
Merge pull request #2201 from hey-api/fix/plugin-transform
Zod: add `name` builders and `case` options
2 parents fcb77c9 + d84c7db commit 5e8f1be

File tree

32 files changed

+2275
-1526
lines changed

32 files changed

+2275
-1526
lines changed

.changeset/famous-ducks-lay.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(zod): generate a single schema for requests
6+
7+
### Single Zod schema per request
8+
9+
Previously, we generated a separate schema for each endpoint parameter and request body. In v0.74.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 zData = z.object({
13+
body: z.object({
14+
foo: z.string().optional(),
15+
bar: z.union([z.number(), z.null()]).optional(),
16+
}).optional(),
17+
headers: z.never().optional(),
18+
path: z.object({
19+
baz: z.string()
20+
}),
21+
query: z.never().optional()
22+
});
23+
```
24+
25+
If you need to access individual fields, you can do so using the [`.shape`](https://zod.dev/api?id=shape) API. For example, we can get the request body schema with `zData.shape.body`.

.changeset/poor-stingrays-remember.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(parser): do not mark schemas as duplicate if they have different format

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.74.0
31+
32+
### Single Zod schema per request
33+
34+
Previously, we generated a separate schema for each endpoint parameter and request body. In v0.74.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 zData = z.object({
38+
body: z
39+
.object({
40+
foo: z.string().optional(),
41+
bar: z.union([z.number(), z.null()]).optional(),
42+
})
43+
.optional(),
44+
headers: z.never().optional(),
45+
path: z.object({
46+
baz: z.string(),
47+
}),
48+
query: z.never().optional(),
49+
});
50+
```
51+
52+
If you need to access individual fields, you can do so using the [`.shape`](https://zod.dev/api?id=shape) API. For example, we can get the request body schema with `zData.shape.body`.
53+
3054
## v0.73.0
3155

3256
### Bundle `@hey-api/client-*` plugins

docs/openapi-ts/plugins/custom.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ import type { Plugin } from '@hey-api/openapi-ts';
110110

111111
import type { Config } from './types';
112112

113-
export const handler: Plugin.Handler<Config> = ({ context, plugin }) => {
113+
export const handler: Plugin.Handler<Config> = ({ plugin }) => {
114114
// create an output file. it will not be
115115
// generated until it contains nodes
116-
const file = context.createFile({
116+
const file = plugin.createFile({
117117
id: plugin.name,
118118
path: plugin.output,
119119
});

docs/openapi-ts/plugins/zod.md

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Launch demo
2626
## Features
2727

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

3131
## Installation
3232

@@ -66,6 +66,32 @@ export default {
6666

6767
The Zod plugin will generate the following artifacts, depending on the input specification.
6868

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 zData = z.object({
75+
body: z
76+
.object({
77+
foo: z.string().optional(),
78+
bar: z.union([z.number(), z.null()]).optional(),
79+
})
80+
.optional(),
81+
headers: z.never().optional(),
82+
path: z.object({
83+
baz: z.string(),
84+
}),
85+
query: z.never().optional(),
86+
});
87+
```
88+
89+
::: tip
90+
If you need to access individual fields, you can do so using the [`.shape`](https://zod.dev/api?id=shape) API. For example, we can get the request body schema with `zData.shape.body`.
91+
:::
92+
93+
You can customize the naming and casing pattern for requests using the `requests.name` and `requests.case` options.
94+
6995
## Responses
7096

7197
A single Zod 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.
@@ -81,30 +107,11 @@ const zResponse = z.union([
81107
]);
82108
```
83109

84-
## Request Bodies
85-
86-
If an endpoint describes a request body, we will generate a Zod schema representing its shape.
87-
88-
```ts
89-
const zData = z.object({
90-
foo: z.string().optional(),
91-
bar: z.union([z.number(), z.null()]).optional(),
92-
});
93-
```
94-
95-
## Parameters
110+
You can customize the naming and casing pattern for responses using the `responses.name` and `responses.case` options.
96111

97-
A separate Zod schema is generated for every request parameter.
112+
## Definitions
98113

99-
```ts
100-
const zParameterFoo = z.number().int();
101-
102-
const zParameterBar = z.string();
103-
```
104-
105-
## Schemas
106-
107-
A separate Zod schema is generated for every reusable schema.
114+
A Zod schema is generated for every reusable definition from your input.
108115

109116
```ts
110117
const zFoo = z.number().int();
@@ -114,9 +121,11 @@ const zBar = z.object({
114121
});
115122
```
116123

124+
You can customize the naming and casing pattern for definitions using the `definitions.name` and `definitions.case` options.
125+
117126
## Metadata
118127

119-
It's often useful to associate a schema with some additional 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.
128+
It's often useful to associate a schema with some additional [metadata](https://zod.dev/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.
120129

121130
```js
122131
export default {

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

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

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

0 commit comments

Comments
 (0)