Skip to content

Commit 32a8d2c

Browse files
authored
Merge pull request #2163 from hey-api/fix/zod-metadata
fix(zod): add metadata option
2 parents c9f3245 + 9769998 commit 32a8d2c

File tree

14 files changed

+208
-23
lines changed

14 files changed

+208
-23
lines changed

.changeset/few-apples-yawn.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(zod): add `metadata` option to generate additional metadata for documentation, code generation, AI structured outputs, form validation, and other purposes

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ layout: home
33

44
hero:
55
name: High-quality tools for interacting with APIs
6-
tagline: Codegen for your TypeScript projects. Trusted over 1,250,000 times each month to generate reliable API clients and SDKs.
6+
tagline: Codegen for your TypeScript projects. Trusted over 1,500,000 times each month to generate reliable API clients and SDKs.
77
actions:
88
- link: /openapi-ts/get-started
99
text: Get Started

docs/openapi-ts/get-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { embedProject } from '../embed'
1313
This package is in initial development. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues).
1414
:::
1515

16-
[@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) is an OpenAPI to TypeScript codegen trusted over 1,250,000 times each month to generate reliable API clients and SDKs. The code is [MIT-licensed](/license) and free to use. Discover available features below or view our [roadmap](https://github.com/orgs/hey-api/discussions/1495) to learn what's coming next.
16+
[@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) is an OpenAPI to TypeScript codegen trusted over 1,500,000 times each month to generate reliable API clients and SDKs. The code is [MIT-licensed](/license) and free to use. Discover available features below or view our [roadmap](https://github.com/orgs/hey-api/discussions/1495) to learn what's coming next.
1717

1818
### Demo
1919

docs/openapi-ts/plugins/zod.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,11 @@ Launch demo
3333
In your [configuration](/openapi-ts/get-started), add `zod` to your plugins and you'll be ready to generate Zod 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
'@hey-api/client-fetch',
4442
'zod', // [!code ++]
4543
],
@@ -51,13 +49,11 @@ export default {
5149
To automatically validate response data in your SDKs, set `sdk.validator` to `true`.
5250

5351
```js
54-
import { defaultPlugins } from '@hey-api/openapi-ts';
55-
5652
export default {
5753
input: 'https://get.heyapi.dev/hey-api/backend',
5854
output: 'src/client',
5955
plugins: [
60-
...defaultPlugins,
56+
// ...other plugins
6157
'@hey-api/client-fetch',
6258
'zod',
6359
{
@@ -120,5 +116,23 @@ const zBar = z.object({
120116
});
121117
```
122118

119+
## Metadata
120+
121+
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.
122+
123+
```js
124+
export default {
125+
input: 'https://get.heyapi.dev/hey-api/backend',
126+
output: 'src/client',
127+
plugins: [
128+
// ...other plugins
129+
{
130+
metadata: true, // [!code ++]
131+
name: 'zod',
132+
},
133+
],
134+
};
135+
```
136+
123137
<!--@include: ../../examples.md-->
124138
<!--@include: ../../sponsors.md-->

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,20 @@ describe(`OpenAPI ${version}`, () => {
717717
}),
718718
description: 'generates validator schemas',
719719
},
720+
{
721+
config: createConfig({
722+
input: 'validators.yaml',
723+
output: 'validators-metadata',
724+
plugins: [
725+
'valibot',
726+
{
727+
metadata: true,
728+
name: 'zod',
729+
},
730+
],
731+
}),
732+
description: 'generates validator schemas with metadata',
733+
},
720734
{
721735
config: createConfig({
722736
input: 'validators-bigint-min-max.json',
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
import * as v from 'valibot';
4+
5+
/**
6+
* This is Bar schema.
7+
*/
8+
export const vBar: v.GenericSchema = v.object({
9+
foo: v.optional(v.lazy(() => {
10+
return vFoo;
11+
}))
12+
});
13+
14+
/**
15+
* This is Foo schema.
16+
*/
17+
export const vFoo: v.GenericSchema = v.optional(v.union([
18+
v.object({
19+
foo: v.optional(v.pipe(v.string(), v.regex(/^\d{3}-\d{2}-\d{4}$/))),
20+
bar: v.optional(vBar),
21+
baz: v.optional(v.array(v.lazy(() => {
22+
return vFoo;
23+
}))),
24+
qux: v.optional(v.pipe(v.number(), v.integer(), v.gtValue(0)), 0)
25+
}),
26+
v.null()
27+
]), null);
28+
29+
export const vBaz = v.optional(v.pipe(v.pipe(v.string(), v.regex(/foo\nbar/)), v.readonly()), 'baz');
30+
31+
/**
32+
* This is Foo parameter.
33+
*/
34+
export const vFoo2 = v.string();
35+
36+
export const vFoo3 = v.object({
37+
foo: v.optional(vBar)
38+
});
39+
40+
export const vPatchFooData = v.object({
41+
foo: v.optional(v.string())
42+
});
43+
44+
/**
45+
* This is Foo parameter.
46+
*/
47+
export const vPatchFooParameterFoo = v.string();
48+
49+
export const vPatchFooParameterBar = vBar;
50+
51+
export const vPatchFooParameterBaz = v.object({
52+
baz: v.optional(v.string())
53+
});
54+
55+
export const vPatchFooParameterQux = v.pipe(v.string(), v.isoDate());
56+
57+
export const vPatchFooParameterQuux = v.pipe(v.string(), v.isoDateTime());
58+
59+
export const vPostFooData = vFoo3;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
import { z } from 'zod';
4+
5+
/**
6+
* This is Bar schema.
7+
*/
8+
export const zBar: z.AnyZodObject = z.object({
9+
foo: z.lazy(() => {
10+
return zFoo;
11+
}).optional()
12+
}).describe('This is Bar schema.');
13+
14+
/**
15+
* This is Foo schema.
16+
*/
17+
export const zFoo: z.ZodTypeAny = z.union([
18+
z.object({
19+
foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).describe('This is foo property.').optional(),
20+
bar: zBar.optional(),
21+
baz: z.array(z.lazy(() => {
22+
return zFoo;
23+
})).describe('This is baz property.').optional(),
24+
qux: z.number().int().gt(0).describe('This is qux property.').optional().default(0)
25+
}),
26+
z.null()
27+
]).default(null);
28+
29+
export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz');
30+
31+
/**
32+
* This is Foo parameter.
33+
*/
34+
export const zFoo2 = z.string().describe('This is Foo parameter.');
35+
36+
export const zFoo3 = z.object({
37+
foo: zBar.optional()
38+
});
39+
40+
export const zPatchFooData = z.object({
41+
foo: z.string().optional()
42+
});
43+
44+
/**
45+
* This is Foo parameter.
46+
*/
47+
export const zPatchFooParameterFoo = z.string().describe('This is Foo parameter.');
48+
49+
export const zPatchFooParameterBar = zBar;
50+
51+
export const zPatchFooParameterBaz = z.object({
52+
baz: z.string().optional()
53+
});
54+
55+
export const zPatchFooParameterQux = z.string().date();
56+
57+
export const zPatchFooParameterQuux = z.string().datetime();
58+
59+
export const zPostFooData = zFoo3;

packages/openapi-ts-tests/test/__snapshots__/3.1.x/validators/valibot.gen.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
import * as v from 'valibot';
44

5+
/**
6+
* This is Bar schema.
7+
*/
58
export const vBar: v.GenericSchema = v.object({
69
foo: v.optional(v.lazy(() => {
710
return vFoo;
811
}))
912
});
1013

14+
/**
15+
* This is Foo schema.
16+
*/
1117
export const vFoo: v.GenericSchema = v.optional(v.union([
1218
v.object({
1319
foo: v.optional(v.pipe(v.string(), v.regex(/^\d{3}-\d{2}-\d{4}$/))),
@@ -23,7 +29,7 @@ export const vFoo: v.GenericSchema = v.optional(v.union([
2329
export const vBaz = v.optional(v.pipe(v.pipe(v.string(), v.regex(/foo\nbar/)), v.readonly()), 'baz');
2430

2531
/**
26-
* aaaaa
32+
* This is Foo parameter.
2733
*/
2834
export const vFoo2 = v.string();
2935

@@ -36,7 +42,7 @@ export const vPatchFooData = v.object({
3642
});
3743

3844
/**
39-
* aaaaa
45+
* This is Foo parameter.
4046
*/
4147
export const vPatchFooParameterFoo = v.string();
4248

packages/openapi-ts-tests/test/__snapshots__/3.1.x/validators/zod.gen.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
import { z } from 'zod';
44

5+
/**
6+
* This is Bar schema.
7+
*/
58
export const zBar: z.AnyZodObject = z.object({
69
foo: z.lazy(() => {
710
return zFoo;
811
}).optional()
912
});
1013

14+
/**
15+
* This is Foo schema.
16+
*/
1117
export const zFoo: z.ZodTypeAny = z.union([
1218
z.object({
1319
foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(),
@@ -23,7 +29,7 @@ export const zFoo: z.ZodTypeAny = z.union([
2329
export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz');
2430

2531
/**
26-
* aaaaa
32+
* This is Foo parameter.
2733
*/
2834
export const zFoo2 = z.string();
2935

@@ -36,7 +42,7 @@ export const zPatchFooData = z.object({
3642
});
3743

3844
/**
39-
* aaaaa
45+
* This is Foo parameter.
4046
*/
4147
export const zPatchFooParameterFoo = z.string();
4248

packages/openapi-ts-tests/test/openapi-ts.config.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,7 @@ export default defineConfig(() => {
5151
// 'invalid',
5252
// 'servers-entry.yaml',
5353
// ),
54-
path: path.resolve(
55-
__dirname,
56-
'spec',
57-
'3.1.x',
58-
'object-property-names.yaml',
59-
),
54+
path: path.resolve(__dirname, 'spec', '3.1.x', 'validators.yaml'),
6055
// path: 'http://localhost:4000/',
6156
// path: 'https://get.heyapi.dev/',
6257
// path: 'https://get.heyapi.dev/hey-api/backend?branch=main&version=1.0.0',
@@ -150,12 +145,13 @@ export default defineConfig(() => {
150145
{
151146
// comments: false,
152147
// exportFromIndex: true,
153-
// name: 'valibot',
148+
name: 'valibot',
154149
},
155150
{
156151
// comments: false,
157152
// exportFromIndex: true,
158-
// name: 'zod',
153+
metadata: true,
154+
name: 'zod',
159155
},
160156
],
161157
// useOptions: false,

0 commit comments

Comments
 (0)