Skip to content

Commit

Permalink
Merge pull request #1394 from hey-api/fix/body-query-accept-unknown-n…
Browse files Browse the repository at this point in the history
…ever

fix: disallow additional query parameters in experimental parser output
  • Loading branch information
mrlubos authored Dec 6, 2024
2 parents 8dd356f + c57ecc3 commit 9f1f456
Show file tree
Hide file tree
Showing 103 changed files with 2,227 additions and 524 deletions.
7 changes: 7 additions & 0 deletions .changeset/rude-nails-know.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: disallow additional query parameters in experimental parser output
1 change: 0 additions & 1 deletion examples/openapi-ts-axios/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './schemas.gen';
export * from './sdk.gen';
export * from './types.gen';
2 changes: 2 additions & 0 deletions examples/openapi-ts-fastify/src/client/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export type ListPetsResponse = ListPetsResponses[keyof ListPetsResponses];

export type CreatePetsData = {
body?: never;
path?: never;
query?: never;
url: '/pets';
};

Expand Down
1 change: 0 additions & 1 deletion examples/openapi-ts-fetch/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './schemas.gen';
export * from './sdk.gen';
export * from './types.gen';
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './schemas.gen';
export * from './sdk.gen';
export * from './types.gen';
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './schemas.gen';
export * from './sdk.gen';
export * from './types.gen';
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './schemas.gen';
export * from './sdk.gen';
export * from './types.gen';
1 change: 0 additions & 1 deletion examples/openapi-ts-tanstack-vue-query/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './schemas.gen'
export * from './sdk.gen'
export * from './types.gen'
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts" setup>
import { PetSchema, type Pet } from '@/client'
import type { Pet } from '@/client'
import { PetSchema } from '@/client/schemas.gen'
import {
addPetMutation,
getPetByIdOptions,
Expand Down
14 changes: 8 additions & 6 deletions packages/client-axios/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AxiosError } from 'axios';
import type { AxiosError, RawAxiosRequestHeaders } from 'axios';
import axios from 'axios';

import type { Client, Config, RequestOptions } from './types';
import type { Client, Config } from './types';
import { createConfig, getUrl, mergeConfigs, mergeHeaders } from './utils';

export const createClient = (config: Config): Client => {
Expand All @@ -24,11 +24,13 @@ export const createClient = (config: Config): Client => {

// @ts-expect-error
const request: Client['request'] = async (options) => {
const opts: RequestOptions = {
const opts = {
..._config,
...options,
// @ts-expect-error
headers: mergeHeaders(_config.headers, options.headers),
headers: mergeHeaders(
_config.headers,
options.headers,
) as RawAxiosRequestHeaders,
};
if (opts.body && opts.bodySerializer) {
opts.body = opts.bodySerializer(opts.body);
Expand Down Expand Up @@ -90,7 +92,7 @@ export type {
Config,
Options,
OptionsLegacyParser,
RequestOptionsBase,
RequestOptions,
RequestResult,
} from './types';
export {
Expand Down
91 changes: 39 additions & 52 deletions packages/client-axios/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
AxiosError,
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
AxiosStatic,
CreateAxiosDefaults,
Expand All @@ -19,12 +18,6 @@ export interface Config<ThrowOnError extends boolean = boolean>
* @default axios
*/
axios?: AxiosStatic;
/**
* Any body that you want to add to your request.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
*/
body?: unknown;
/**
* A function for serializing request body parameter. By default,
* {@link JSON.stringify()} will be used.
Expand Down Expand Up @@ -76,10 +69,22 @@ export interface Config<ThrowOnError extends boolean = boolean>
throwOnError?: ThrowOnError;
}

export interface RequestOptionsBase<
ThrowOnError extends boolean,
export interface RequestOptions<
ThrowOnError extends boolean = false,
Url extends string = string,
> extends Config<ThrowOnError> {
/**
* Any body that you want to add to your request.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
*/
body?: unknown;
/**
* You can provide a client instance returned by `createClient()` instead of
* individual options. This might be also useful if you want to implement a
* custom client.
*/
client?: Client;
path?: Record<string, unknown>;
query?: Record<string, unknown>;
url: Url;
Expand All @@ -101,16 +106,16 @@ type MethodFn = <
TError = unknown,
ThrowOnError extends boolean = false,
>(
options: Omit<RequestOptionsBase<ThrowOnError>, 'method'>,
options: Omit<RequestOptions<ThrowOnError>, 'method'>,
) => RequestResult<Data, TError, ThrowOnError>;

type RequestFn = <
Data = unknown,
TError = unknown,
ThrowOnError extends boolean = false,
>(
options: Omit<RequestOptionsBase<ThrowOnError>, 'method'> &
Pick<Required<RequestOptionsBase<ThrowOnError>>, 'method'>,
options: Omit<RequestOptions<ThrowOnError>, 'method'> &
Pick<Required<RequestOptions<ThrowOnError>>, 'method'>,
) => RequestResult<Data, TError, ThrowOnError>;

export interface Client {
Expand All @@ -127,49 +132,31 @@ export interface Client {
setConfig: (config: Config) => Config;
}

export type RequestOptions = RequestOptionsBase<false> &
Config<false> & {
headers: AxiosRequestConfig['headers'];
};

type OptionsBase<ThrowOnError extends boolean> = Omit<
RequestOptionsBase<ThrowOnError>,
'url'
> & {
/**
* You can provide a client instance returned by `createClient()` instead of
* individual options. This might be also useful if you want to implement a
* custom client.
*/
client?: Client;
};
interface DataShape {
body?: unknown;
headers?: unknown;
path?: unknown;
query?: unknown;
url: string;
}

export type Options<
T extends { url: string } = { url: string },
Data extends DataShape = DataShape,
ThrowOnError extends boolean = boolean,
> = T extends { body?: any }
? T extends { headers?: any }
? OmitKeys<OptionsBase<ThrowOnError>, 'body' | 'headers'> & Omit<T, 'url'>
: OmitKeys<OptionsBase<ThrowOnError>, 'body'> &
Omit<T, 'url'> &
Pick<OptionsBase<ThrowOnError>, 'headers'>
: T extends { headers?: any }
? OmitKeys<OptionsBase<ThrowOnError>, 'headers'> &
Omit<T, 'url'> &
Pick<OptionsBase<ThrowOnError>, 'body'>
: OptionsBase<ThrowOnError> & Omit<T, 'url'>;
> = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> &
Omit<Data, 'url'>;

export type OptionsLegacyParser<
T = unknown,
Data = unknown,
ThrowOnError extends boolean = boolean,
> = T extends { body?: any }
? T extends { headers?: any }
? OmitKeys<OptionsBase<ThrowOnError>, 'body' | 'headers'> & T
: OmitKeys<OptionsBase<ThrowOnError>, 'body'> &
T &
Pick<OptionsBase<ThrowOnError>, 'headers'>
: T extends { headers?: any }
? OmitKeys<OptionsBase<ThrowOnError>, 'headers'> &
T &
Pick<OptionsBase<ThrowOnError>, 'body'>
: OptionsBase<ThrowOnError> & T;
> = Data extends { body?: any }
? Data extends { headers?: any }
? OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'headers' | 'url'> & Data
: OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'url'> &
Data &
Pick<RequestOptions<ThrowOnError>, 'headers'>
: Data extends { headers?: any }
? OmitKeys<RequestOptions<ThrowOnError>, 'headers' | 'url'> &
Data &
Pick<RequestOptions<ThrowOnError>, 'body'>
: OmitKeys<RequestOptions<ThrowOnError>, 'url'> & Data;
5 changes: 2 additions & 3 deletions packages/client-fetch/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ export const createClient = (config: Config = {}): Client => {

// @ts-expect-error
const request: Client['request'] = async (options) => {
// @ts-expect-error
const opts: RequestOptions = {
const opts = {
..._config,
...options,
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
Expand Down Expand Up @@ -170,7 +169,7 @@ export type {
Config,
Options,
OptionsLegacyParser,
RequestOptionsBase,
RequestOptions,
RequestResult,
} from './types';
export {
Expand Down
Loading

0 comments on commit 9f1f456

Please sign in to comment.