Skip to content

Commit

Permalink
Merge pull request #1333 from hey-api/feat/client-fetch-build-url
Browse files Browse the repository at this point in the history
feat: add buildUrl() method to fetch client
  • Loading branch information
mrlubos authored Nov 24, 2024
2 parents 44a5219 + 734a62d commit a25d51b
Show file tree
Hide file tree
Showing 160 changed files with 8,111 additions and 3,131 deletions.
7 changes: 7 additions & 0 deletions .changeset/little-days-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@hey-api/client-axios': patch
'@hey-api/client-fetch': patch
'@hey-api/openapi-ts': patch
---

fix: experimental parser generates url inside data types
34 changes: 34 additions & 0 deletions .changeset/modern-walls-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
'@hey-api/client-fetch': minor
---

## Build URL

::: warning
To use this feature, you must opt in to the [experimental parser](/openapi-ts/configuration#parser).
:::

If you need to access the compiled URL, you can use the `buildUrl()` method. It's loosely typed by default to accept almost any value; in practice, you will want to pass a type hint.

```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};

const url = client.buildUrl<FooData>({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url) // prints '/foo/1?bar=baz'
```
40 changes: 32 additions & 8 deletions docs/.vitepress/config/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@ export default defineConfig({
sidebar: [
{
items: [
{ link: '/openapi-ts/get-started', text: 'Get Started' },
{ link: '/openapi-ts/configuration', text: 'Configuration' },
{
link: '/openapi-ts/get-started',
text: 'Get Started',
},
{
link: '/openapi-ts/configuration',
text: 'Configuration',
},
],
text: '@hey-api/openapi-ts',
},
{
items: [
{ link: '/openapi-ts/output', text: 'Output' },
{
link: '/openapi-ts/output',
text: 'Output',
},
{
collapsed: true,
items: [
Expand All @@ -41,7 +50,10 @@ export default defineConfig({
link: '/openapi-ts/clients',
text: 'Clients',
},
{ link: '/openapi-ts/transformers', text: 'Transformers' },
{
link: '/openapi-ts/transformers',
text: 'Transformers',
},
],
text: 'Guides and Concepts',
},
Expand Down Expand Up @@ -77,10 +89,22 @@ export default defineConfig({
},
{
items: [
{ link: '/openapi-ts/migrating', text: 'Migrating' },
{ link: '/license', text: 'License' },
{ link: '/about', text: 'Philosophy' },
{ link: '/contributing', text: 'Contributing' },
{
link: '/openapi-ts/migrating',
text: 'Migrating',
},
{
link: '/license',
text: 'License',
},
{
link: '/about',
text: 'Philosophy',
},
{
link: '/contributing',
text: 'Contributing',
},
],
text: '@hey-api',
},
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/clients/axios.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ client.instance.interceptors.request.use((config) => {

## Customization

Our Axios client is built as a thin wrapper on top of Axios, extending its functionality to work with Hey API. If you're already familiar with Axios, customizing your client will feel like working directly with Axios. You can customize requests in three ways – through SDKs, per client, or per request.
The Axios client is built as a thin wrapper on top of Axios, extending its functionality to work with Hey API. If you're already familiar with Axios, customizing your client will feel like working directly with Axios. You can customize requests in three ways – through SDKs, per client, or per request.

### SDKs

Expand Down
33 changes: 32 additions & 1 deletion docs/openapi-ts/clients/fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ To eject, you must provide a reference to the function that was passed to `use()

## Customization

Our Fetch client is built as a thin wrapper on top of Fetch API, extending its functionality to work with Hey API. If you're already familiar with Fetch, customizing your client will feel like working directly with Fetch API. You can customize requests in three ways – through SDKs, per client, or per request.
The Fetch client is built as a thin wrapper on top of Fetch API, extending its functionality to work with Hey API. If you're already familiar with Fetch, customizing your client will feel like working directly with Fetch API. You can customize requests in three ways – through SDKs, per client, or per request.

### SDKs

Expand Down Expand Up @@ -179,6 +179,37 @@ const response = await getFoo({
});
```

## Build URL

::: warning
To use this feature, you must opt in to the [experimental parser](/openapi-ts/configuration#parser).
:::

If you need to access the compiled URL, you can use the `buildUrl()` method. It's loosely typed by default to accept almost any value; in practice, you will want to pass a type hint.

```ts
type FooData = {
path: {
fooId: number;
};
query?: {
bar?: string;
};
url: '/foo/{fooId}';
};

const url = client.buildUrl<FooData>({
path: {
fooId: 1,
},
query: {
bar: 'baz',
},
url: '/foo/{fooId}',
});
console.log(url); // prints '/foo/1?bar=baz'
```

## Bundling

Sometimes, you may not want to declare client packages as a dependency. This scenario is common if you're using Hey API to generate output that is repackaged and published for other consumers under your own brand. For such cases, our clients support bundling through the `client.bundle` configuration option.
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ We use [`@apidevtools/json-schema-ref-parser`](https://github.com/APIDevTools/js
## Filters

::: warning
Filters work only with the [experimental parser](#parser) which is currently an opt-in feature.
To use this feature, you must opt in to the [experimental parser](#parser).
:::

If you work with large specifications and want to generate output from their subset, you can use regular expressions to select the relevant definitions. Set `input.include` to match resource references to be included or `input.exclude` to match resource references to be excluded. When both regular expressions match the same definition, `input.exclude` takes precedence over `input.include`.
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/fastify.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Live demo
## Installation

::: warning
Fastify plugin works only with the [experimental parser](/openapi-ts/configuration#parser) which is currently an opt-in feature.
To use this feature, you must opt in to the [experimental parser](/openapi-ts/configuration#parser).
:::

Ensure you have already [configured](/openapi-ts/get-started) `@hey-api/openapi-ts`. Update your configuration to use the Fastify plugin.
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-ts/zod.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Live demo
## Installation

::: warning
Zod plugin works only with the [experimental parser](/openapi-ts/configuration#parser) which is currently an opt-in feature.
To use this feature, you must opt in to the [experimental parser](/openapi-ts/configuration#parser).
:::

Ensure you have already [configured](/openapi-ts/get-started) `@hey-api/openapi-ts`. Update your configuration to use the Zod plugin.
Expand Down
40 changes: 20 additions & 20 deletions examples/openapi-ts-axios/src/client/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {
createClient,
createConfig,
type Options,
type OptionsLegacyParser,
} from '@hey-api/client-axios';

import type {
Expand Down Expand Up @@ -63,7 +63,7 @@ export const client = createClient(createConfig());
* Add a new pet to the store
*/
export const addPet = <ThrowOnError extends boolean = false>(
options: Options<AddPetData, ThrowOnError>,
options: OptionsLegacyParser<AddPetData, ThrowOnError>,
) =>
(options?.client ?? client).post<AddPetResponse, AddPetError, ThrowOnError>({
...options,
Expand All @@ -75,7 +75,7 @@ export const addPet = <ThrowOnError extends boolean = false>(
* Update an existing pet by Id
*/
export const updatePet = <ThrowOnError extends boolean = false>(
options: Options<UpdatePetData, ThrowOnError>,
options: OptionsLegacyParser<UpdatePetData, ThrowOnError>,
) =>
(options?.client ?? client).put<
UpdatePetResponse,
Expand All @@ -91,7 +91,7 @@ export const updatePet = <ThrowOnError extends boolean = false>(
* Multiple status values can be provided with comma separated strings
*/
export const findPetsByStatus = <ThrowOnError extends boolean = false>(
options?: Options<FindPetsByStatusData, ThrowOnError>,
options?: OptionsLegacyParser<FindPetsByStatusData, ThrowOnError>,
) =>
(options?.client ?? client).get<
FindPetsByStatusResponse,
Expand All @@ -107,7 +107,7 @@ export const findPetsByStatus = <ThrowOnError extends boolean = false>(
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
*/
export const findPetsByTags = <ThrowOnError extends boolean = false>(
options?: Options<FindPetsByTagsData, ThrowOnError>,
options?: OptionsLegacyParser<FindPetsByTagsData, ThrowOnError>,
) =>
(options?.client ?? client).get<
FindPetsByTagsResponse,
Expand All @@ -123,7 +123,7 @@ export const findPetsByTags = <ThrowOnError extends boolean = false>(
* Returns a single pet
*/
export const getPetById = <ThrowOnError extends boolean = false>(
options: Options<GetPetByIdData, ThrowOnError>,
options: OptionsLegacyParser<GetPetByIdData, ThrowOnError>,
) =>
(options?.client ?? client).get<
GetPetByIdResponse,
Expand All @@ -138,7 +138,7 @@ export const getPetById = <ThrowOnError extends boolean = false>(
* Updates a pet in the store with form data
*/
export const updatePetWithForm = <ThrowOnError extends boolean = false>(
options: Options<UpdatePetWithFormData, ThrowOnError>,
options: OptionsLegacyParser<UpdatePetWithFormData, ThrowOnError>,
) =>
(options?.client ?? client).post<void, unknown, ThrowOnError>({
...options,
Expand All @@ -149,7 +149,7 @@ export const updatePetWithForm = <ThrowOnError extends boolean = false>(
* Deletes a pet
*/
export const deletePet = <ThrowOnError extends boolean = false>(
options: Options<DeletePetData, ThrowOnError>,
options: OptionsLegacyParser<DeletePetData, ThrowOnError>,
) =>
(options?.client ?? client).delete<void, unknown, ThrowOnError>({
...options,
Expand All @@ -160,7 +160,7 @@ export const deletePet = <ThrowOnError extends boolean = false>(
* uploads an image
*/
export const uploadFile = <ThrowOnError extends boolean = false>(
options: Options<UploadFileData, ThrowOnError>,
options: OptionsLegacyParser<UploadFileData, ThrowOnError>,
) =>
(options?.client ?? client).post<
UploadFileResponse,
Expand All @@ -176,7 +176,7 @@ export const uploadFile = <ThrowOnError extends boolean = false>(
* Returns a map of status codes to quantities
*/
export const getInventory = <ThrowOnError extends boolean = false>(
options?: Options<unknown, ThrowOnError>,
options?: OptionsLegacyParser<unknown, ThrowOnError>,
) =>
(options?.client ?? client).get<
GetInventoryResponse,
Expand All @@ -192,7 +192,7 @@ export const getInventory = <ThrowOnError extends boolean = false>(
* Place a new order in the store
*/
export const placeOrder = <ThrowOnError extends boolean = false>(
options?: Options<PlaceOrderData, ThrowOnError>,
options?: OptionsLegacyParser<PlaceOrderData, ThrowOnError>,
) =>
(options?.client ?? client).post<
PlaceOrderResponse,
Expand All @@ -208,7 +208,7 @@ export const placeOrder = <ThrowOnError extends boolean = false>(
* For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.
*/
export const getOrderById = <ThrowOnError extends boolean = false>(
options: Options<GetOrderByIdData, ThrowOnError>,
options: OptionsLegacyParser<GetOrderByIdData, ThrowOnError>,
) =>
(options?.client ?? client).get<
GetOrderByIdResponse,
Expand All @@ -224,7 +224,7 @@ export const getOrderById = <ThrowOnError extends boolean = false>(
* For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
*/
export const deleteOrder = <ThrowOnError extends boolean = false>(
options: Options<DeleteOrderData, ThrowOnError>,
options: OptionsLegacyParser<DeleteOrderData, ThrowOnError>,
) =>
(options?.client ?? client).delete<void, unknown, ThrowOnError>({
...options,
Expand All @@ -236,7 +236,7 @@ export const deleteOrder = <ThrowOnError extends boolean = false>(
* This can only be done by the logged in user.
*/
export const createUser = <ThrowOnError extends boolean = false>(
options?: Options<CreateUserData, ThrowOnError>,
options?: OptionsLegacyParser<CreateUserData, ThrowOnError>,
) =>
(options?.client ?? client).post<
CreateUserResponse,
Expand All @@ -252,7 +252,7 @@ export const createUser = <ThrowOnError extends boolean = false>(
* Creates list of users with given input array
*/
export const createUsersWithListInput = <ThrowOnError extends boolean = false>(
options?: Options<CreateUsersWithListInputData, ThrowOnError>,
options?: OptionsLegacyParser<CreateUsersWithListInputData, ThrowOnError>,
) =>
(options?.client ?? client).post<
CreateUsersWithListInputResponse,
Expand All @@ -267,7 +267,7 @@ export const createUsersWithListInput = <ThrowOnError extends boolean = false>(
* Logs user into the system
*/
export const loginUser = <ThrowOnError extends boolean = false>(
options?: Options<LoginUserData, ThrowOnError>,
options?: OptionsLegacyParser<LoginUserData, ThrowOnError>,
) =>
(options?.client ?? client).get<
LoginUserResponse,
Expand All @@ -282,7 +282,7 @@ export const loginUser = <ThrowOnError extends boolean = false>(
* Logs out current logged in user session
*/
export const logoutUser = <ThrowOnError extends boolean = false>(
options?: Options<unknown, ThrowOnError>,
options?: OptionsLegacyParser<unknown, ThrowOnError>,
) =>
(options?.client ?? client).get<
LogoutUserResponse,
Expand All @@ -297,7 +297,7 @@ export const logoutUser = <ThrowOnError extends boolean = false>(
* Get user by user name
*/
export const getUserByName = <ThrowOnError extends boolean = false>(
options: Options<GetUserByNameData, ThrowOnError>,
options: OptionsLegacyParser<GetUserByNameData, ThrowOnError>,
) =>
(options?.client ?? client).get<
GetUserByNameResponse,
Expand All @@ -313,7 +313,7 @@ export const getUserByName = <ThrowOnError extends boolean = false>(
* This can only be done by the logged in user.
*/
export const updateUser = <ThrowOnError extends boolean = false>(
options: Options<UpdateUserData, ThrowOnError>,
options: OptionsLegacyParser<UpdateUserData, ThrowOnError>,
) =>
(options?.client ?? client).put<
UpdateUserResponse,
Expand All @@ -329,7 +329,7 @@ export const updateUser = <ThrowOnError extends boolean = false>(
* This can only be done by the logged in user.
*/
export const deleteUser = <ThrowOnError extends boolean = false>(
options: Options<DeleteUserData, ThrowOnError>,
options: OptionsLegacyParser<DeleteUserData, ThrowOnError>,
) =>
(options?.client ?? client).delete<void, unknown, ThrowOnError>({
...options,
Expand Down
3 changes: 2 additions & 1 deletion examples/openapi-ts-fastify/src/client/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@hey-api/client-fetch';

import type {
CreatePetsData,
CreatePetsError,
ListPetsData,
ListPetsError,
Expand Down Expand Up @@ -37,7 +38,7 @@ export const listPets = <ThrowOnError extends boolean = false>(
* Create a pet
*/
export const createPets = <ThrowOnError extends boolean = false>(
options?: Options<unknown, ThrowOnError>,
options?: Options<CreatePetsData, ThrowOnError>,
) =>
(options?.client ?? client).post<unknown, CreatePetsError, ThrowOnError>({
...options,
Expand Down
Loading

0 comments on commit a25d51b

Please sign in to comment.