Skip to content

Commit

Permalink
Merge pull request #1430 from hey-api/fix/zod-schema-response
Browse files Browse the repository at this point in the history
fix: generate response zod schemas
  • Loading branch information
mrlubos authored Dec 13, 2024
2 parents 8095505 + 9cec9e8 commit 42a9920
Show file tree
Hide file tree
Showing 49 changed files with 1,433 additions and 537 deletions.
30 changes: 30 additions & 0 deletions .changeset/fluffy-beans-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
'@hey-api/openapi-ts': minor
---

fix: require sdk.transformer to use generated transformers

### Added `sdk.transformer` option

When generating SDKs, you now have to specify `transformer` in order to modify response data. By default, adding `@hey-api/transformers` to your plugins will only produce additional output. To preserve the previous functionality, set `sdk.transformer` to `true`.

```js
import { defaultPlugins } from '@hey-api/openapi-ts';

export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
dates: true,
name: '@hey-api/transformers',
},
{
name: '@hey-api/sdk',
transformer: true, // [!code ++]
},
],
};
```
5 changes: 5 additions & 0 deletions .changeset/lazy-moose-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hey-api/docs': patch
---

docs: add validators page
6 changes: 6 additions & 0 deletions .changeset/polite-houses-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@hey-api/client-axios': patch
'@hey-api/client-fetch': patch
---

fix: add responseValidator option
5 changes: 5 additions & 0 deletions .changeset/shiny-birds-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hey-api/openapi-ts': patch
---

feat: Zod plugin generates response schemas
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ jobs:
run: pnpm test:e2e

- name: Publish previews
if: matrix.node-version == '21.x' && matrix.os == 'ubuntu-latest'
if: matrix.node-version == '22.x' && matrix.os == 'ubuntu-latest'
run: pnpx pkg-pr-new publish --compact --pnpm './packages/*'
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ Love Hey API? Please consider becoming a [sponsor](https://github.com/sponsors/h

Automatically update your code when the APIs it depends on change. [Find out more](https://heyapi.dev/openapi-ts/integrations.html).

## Migrating from OpenAPI Typescript Codegen?
## Migration Guides

Please read our [migration guide](https://heyapi.dev/openapi-ts/migrating.html#openapi-typescript-codegen).

## Contributing

Want to get involved? Please refer to the [contributing guide](https://heyapi.dev/contributing.html).
[OpenAPI Typescript Codegen](https://heyapi.dev/openapi-ts/migrating.html#openapi-typescript-codegen).
15 changes: 11 additions & 4 deletions docs/.vitepress/config/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ export default defineConfig({
link: '/openapi-ts/clients',
text: 'Clients',
},
{
collapsed: true,
items: [
{
link: '/openapi-ts/validators/zod',
text: 'Zod',
},
],
link: '/openapi-ts/validators',
text: 'Validators',
},
{
link: '/openapi-ts/transformers',
text: 'Transformers',
Expand All @@ -71,10 +82,6 @@ export default defineConfig({
link: '/openapi-ts/tanstack-query',
text: 'TanStack Query',
},
{
link: '/openapi-ts/zod',
text: 'Zod',
},
],
text: 'Plugins',
},
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ features:

<div class="home-list">

### Migration guides
### Migration Guides

- [OpenAPI TypeScript Codegen](/openapi-ts/migrating#openapi-typescript-codegen)

Expand Down
1 change: 1 addition & 0 deletions docs/openapi-ts/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ We all send HTTP requests in a slightly different way. Hey API doesn't force you

- seamless integration with `@hey-api/openapi-ts` ecosystem
- type-safe response data and errors
- response data validation and transformation
- access to the original request and response
- granular request and response customization options
- minimal learning curve thanks to extending the underlying technology
Expand Down
27 changes: 27 additions & 0 deletions docs/openapi-ts/migrating.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@ This config option is deprecated and will be removed in favor of [clients](./cli

This config option is deprecated and will be removed.

## v0.60.0

### Added `sdk.transformer` option

When generating SDKs, you now have to specify `transformer` in order to modify response data. By default, adding `@hey-api/transformers` to your plugins will only produce additional output. To preserve the previous functionality, set `sdk.transformer` to `true`.

```js
import { defaultPlugins } from '@hey-api/openapi-ts';

export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
{
dates: true,
name: '@hey-api/transformers',
},
{
name: '@hey-api/sdk',
transformer: true, // [!code ++]
},
],
};
```

## v0.59.0

### Added `logs.level` option
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ These plugins help reduce boilerplate associated with third-party dependencies.
- [`@tanstack/svelte-query`](/openapi-ts/tanstack-query) - TanStack Query functions and query keys
- [`@tanstack/vue-query`](/openapi-ts/tanstack-query) - TanStack Query functions and query keys
- [`fastify`](/openapi-ts/fastify) - TypeScript interface for Fastify route handlers
- [`zod`](/openapi-ts/zod) - Zod schemas to validate your data
- [`zod`](/openapi-ts/validators/zod) - Zod schemas to validate your data

## Community

Expand Down
42 changes: 41 additions & 1 deletion docs/openapi-ts/transformers.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Transformers
description: Learn about transforming payloads with @hey-api/openapi-ts.
description: Learn about transforming data with @hey-api/openapi-ts.
---

# Transformers
Expand All @@ -27,6 +27,46 @@ Transformers handle only the most common scenarios. Some of the known limitation

If your data isn't being transformed as expected, we encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues).

## Configuration

To generate transformers, add `@hey-api/transformers` to your plugins.

```js
import { defaultPlugins } from '@hey-api/openapi-ts';

export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
'@hey-api/transformers', // [!code ++]
],
};
```

## SDKs

To automatically transform response data in your SDKs, set `transformer` to `true`.

```js
import { defaultPlugins } from '@hey-api/openapi-ts';

export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
'@hey-api/transformers',
{
name: '@hey-api/sdk', // [!code ++]
transformer: true, // [!code ++]
},
],
};
```

## Dates

To convert date strings into `Date` objects, use the `dates` configuration option.
Expand Down
62 changes: 62 additions & 0 deletions docs/openapi-ts/validators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: Validators
description: Learn about validating data with @hey-api/openapi-ts.
---

# Validators

There are times when you cannot blindly trust the server to return the correct data. You might be working on a critical application where any mistakes would be costly, or you're simply dealing with a legacy or undocumented system.

Hey API clients support validating responses so you can rest assured that you're working with the correct data.

## Available Validators

- [Zod](/openapi-ts/validators/zod)
- [Ajv](https://ajv.js.org/) <span class="soon">Soon</span>
- [Joi](https://joi.dev/) <span class="soon">Soon</span>
- [Yup](https://github.com/jquense/yup) <span class="soon">Soon</span>

If you'd like Hey API to support your validator, let us know by [opening an issue](https://github.com/hey-api/openapi-ts/issues).

## Installation

There are two ways to generate validators. If you only need response validation in your SDKs, set `sdk.validator` to the desired value. For a more granular approach, add the validator to your plugins and set `sdk.validator` to `true`.

::: code-group

```js [sdk]
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
{
name: '@hey-api/sdk',
validator: 'zod', // [!code ++]
},
],
};
```

```js [validator]
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
{
name: '@hey-api/sdk',
validator: true, // [!code ++]
},
{
name: 'zod', // [!code ++]
// other options
},
],
};
```

:::

<!--@include: ../examples.md-->
<!--@include: ../sponsorship.md-->
26 changes: 24 additions & 2 deletions docs/openapi-ts/zod.md → docs/openapi-ts/validators/zod.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ export default {

You can now generate Zod artifacts. 🎉

## SDKs

To automatically validate response data in your SDKs, set `validator` to `true`.

```js
import { defaultPlugins } from '@hey-api/openapi-ts';

export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
...defaultPlugins,
'zod',
{
name: '@hey-api/sdk', // [!code ++]
validator: true, // [!code ++]
},
],
};
```

## Output

The Zod plugin will generate the following artifacts, depending on the input specification.
Expand All @@ -53,5 +75,5 @@ The Zod plugin will generate the following artifacts, depending on the input spe

More information will be provided as we finalize the plugin.

<!--@include: ../examples.md-->
<!--@include: ../sponsorship.md-->
<!--@include: ../../examples.md-->
<!--@include: ../../sponsorship.md-->
9 changes: 3 additions & 6 deletions packages/client-axios/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

- seamless integration with `@hey-api/openapi-ts` ecosystem
- type-safe response data and errors
- response data validation and transformation
- access to the original request and response
- granular request and response customization options
- minimal learning curve thanks to extending the underlying technology
Expand All @@ -27,10 +28,6 @@ Love Hey API? Please consider becoming a [sponsor](https://github.com/sponsors/h

Automatically update your code when the APIs it depends on change. [Find out more](https://heyapi.dev/openapi-ts/integrations.html).

## Migrating from OpenAPI Typescript Codegen?
## Migration Guides

Please read our [migration guide](https://heyapi.dev/openapi-ts/migrating.html#openapi-typescript-codegen).

## Contributing

Want to get involved? Please refer to the [contributing guide](https://heyapi.dev/contributing.html).
[OpenAPI Typescript Codegen](https://heyapi.dev/openapi-ts/migrating.html#openapi-typescript-codegen).
10 changes: 8 additions & 2 deletions packages/client-axios/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,14 @@ export const createClient = (config: Config): Client => {

let { data } = response;

if (opts.responseType === 'json' && opts.responseTransformer) {
data = await opts.responseTransformer(data);
if (opts.responseType === 'json') {
if (opts.responseValidator) {
await opts.responseValidator(data);
}

if (opts.responseTransformer) {
data = await opts.responseTransformer(data);
}
}

return {
Expand Down
13 changes: 9 additions & 4 deletions packages/client-axios/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,16 @@ export interface Config<ThrowOnError extends boolean = boolean>
*/
querySerializer?: QuerySerializer | QuerySerializerOptions;
/**
* A function for transforming response data before it's returned to the
* caller function. This is an ideal place to post-process server data,
* e.g. convert date ISO strings into native Date objects.
* A function transforming response data before it's returned. This is useful
* for post-processing data, e.g. converting ISO strings into Date objects.
*/
responseTransformer?: (data: unknown) => Promise<unknown>;
/**
* A function validating response data. This is useful if you want to ensure
* the response conforms to the desired shape, so it can be safely passed to
* the transformers and returned to the user.
*/
responseValidator?: (data: unknown) => Promise<unknown>;
/**
* Throw an error instead of returning it in the response?
*
Expand All @@ -97,7 +102,7 @@ export interface Config<ThrowOnError extends boolean = boolean>
}

export interface RequestOptions<
ThrowOnError extends boolean = false,
ThrowOnError extends boolean = boolean,
Url extends string = string,
> extends Config<ThrowOnError> {
/**
Expand Down
Loading

0 comments on commit 42a9920

Please sign in to comment.