Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make all params optional #858 #894

Merged
merged 12 commits into from
Nov 30, 2023
2 changes: 1 addition & 1 deletion docs/src/pages/guides/custom-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const customInstance = async <T>({
data,
}: {
url: string;
method: 'get' | 'post' | 'put' | 'delete' | 'patch';
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
params?: any;
data?: BodyType<unknown>;
responseType?: string;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
"update-samples": "zx ./scripts/update-samples.mjs",
"build": "turbo run build",
"test": "turbo run test",
"test:ci": "yarn test -- -- --run && yarn test:vue-query --run",
"test:ci": "yarn test -- -- --run && yarn test:vue-query",
"test:vue-query": "cd ./samples/vue-query && yarn && yarn test",
"test:react-query:custom-client": "cd ./samples/react-query/custom-client && yarn && yarn test",
"lint": "turbo run lint",
"dev": "turbo run dev"
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/generators/verbs-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const generateVerbOptions = async ({
pathParams: parameters.path,
operationId: operationId!,
context,
output,
});

const props = getProps({
Expand Down
18 changes: 15 additions & 3 deletions packages/core/src/getters/params.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { resolveValue } from '../resolvers';
import { ContextSpecs, GetterParameters, GetterParams } from '../types';
import {
ContextSpecs,
GetterParameters,
GetterParams,
NormalizedOutputOptions,
} from '../types';
import { camel, sanitize, stringify } from '../utils';

/**
Expand Down Expand Up @@ -29,11 +34,13 @@ export const getParams = ({
pathParams = [],
operationId,
context,
output,
}: {
route: string;
pathParams?: GetterParameters['query'];
operationId: string;
context: ContextSpecs;
output: NormalizedOutputOptions;
}): GetterParams => {
const params = getParamsInPath(route);
return params.map((p) => {
Expand Down Expand Up @@ -83,6 +90,11 @@ export const getParams = ({
},
});

let paramType = resolvedValue.value;
if (output.allParamsOptional) {
paramType = `${paramType} | undefined | null`; // TODO: maybe check that `paramType` isn't already undefined or null
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the core change directly related to the issue

}

const definition = `${name}${
!required || resolvedValue.originalSchema!.default ? '?' : ''
}: ${resolvedValue.value}`;
Expand All @@ -91,8 +103,8 @@ export const getParams = ({
!required && !resolvedValue.originalSchema!.default ? '?' : ''
}${
!resolvedValue.originalSchema!.default
? `: ${resolvedValue.value}`
: `= ${stringify(resolvedValue.originalSchema!.default)}`
? `: ${paramType}`
: `: ${paramType} = ${stringify(resolvedValue.originalSchema!.default)}` // FIXME: in Vue if we have `version: MaybeRef<number | undefined | null> = 1` and we don't pass version, the unref(version) will be `undefined` and not `1`, so we need to handle default value somewhere in implementation and not in the definition
}`;

return {
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/getters/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ export const getProps = ({

const implementation = `{ ${params
.map((property) =>
property.default ? property.implementation : property.name,
property.default
? `${property.name} = ${property.default}` // if we use property.implementation, we will get `{ version: number = 1 }: ListPetsPathParameters = {}` which isn't valid
: property.name,
)
.join(', ')} }: ${parameterTypeName}${isOptional ? ' = {}' : ''}`;

Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export type NormalizedOutputOptions = {
headers: boolean;
indexFiles: boolean;
baseUrl?: string;
allParamsOptional: boolean;
};

export type NormalizedParamsSerializerOptions = {
Expand Down Expand Up @@ -170,6 +171,7 @@ export type OutputOptions = {
headers?: boolean;
indexFiles?: boolean;
baseUrl?: string;
allParamsOptional?: boolean;
};

export type SwaggerParserOptions = Omit<SwaggerParser.Options, 'validate'> & {
Expand All @@ -194,6 +196,7 @@ export const OutputClient = {
REACT_QUERY: 'react-query',
SVELTE_QUERY: 'svelte-query',
VUE_QUERY: 'vue-query',
SWR: 'swr',
} as const;

export type OutputClient = typeof OutputClient[keyof typeof OutputClient];
Expand Down
1 change: 1 addition & 0 deletions packages/orval/src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ export const normalizeOptions = async (
outputOptions.override?.useDeprecatedOperations ?? true,
useNativeEnums: outputOptions.override?.useNativeEnums ?? false,
},
allParamsOptional: outputOptions.allParamsOptional ?? false,
},
hooks: options.hooks ? normalizeHooks(options.hooks) : {},
};
Expand Down
6 changes: 3 additions & 3 deletions samples/angular-app/src/api/endpoints/pets/pets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class PetsService {
/**
* @summary List all pets
*/
listPets<TData = Pets>(params?: ListPetsParams, version = 1) {
listPets<TData = Pets>(params?: ListPetsParams, version: number = 1) {
return listPetsMutator<TData>(
{ url: `/v${version}/pets`, method: 'GET', params },
this.http,
Expand All @@ -54,7 +54,7 @@ export class PetsService {
*/
createPets<TData = void>(
createPetsBody: CreatePetsBody,
version = 1,
version: number = 1,
options?: HttpClientOptions,
): Observable<TData> {
return this.http.post<TData>(`/v${version}/pets`, createPetsBody, options);
Expand All @@ -64,7 +64,7 @@ export class PetsService {
*/
showPetById<TData = Pet>(
petId: string,
version = 1,
version: number = 1,
options?: HttpClientOptions,
): Observable<TData> {
return this.http.get<TData>(`/v${version}/pets/${petId}`, options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import listPetsMutator from '../mutator/response-type';
/**
* @summary List all pets
*/
export const listPets = (params?: ListPetsParams, version = 1) => {
export const listPets = (params?: ListPetsParams, version: number = 1) => {
return listPetsMutator<Pets>({
url: `/v${version}/pets`,
method: 'GET',
Expand All @@ -27,7 +27,7 @@ export const listPets = (params?: ListPetsParams, version = 1) => {
*/
export const createPets = <TData = AxiosResponse<void>>(
createPetsBody: CreatePetsBody,
version = 1,
version: number = 1,
options?: AxiosRequestConfig,
): Promise<TData> => {
return axios.post(`/v${version}/pets`, createPetsBody, options);
Expand All @@ -38,7 +38,7 @@ export const createPets = <TData = AxiosResponse<void>>(
*/
export const showPetById = <TData = AxiosResponse<Pet>>(
petId: string,
version = 1,
version: number = 1,
options?: AxiosRequestConfig,
): Promise<TData> => {
return axios.get(`/v${version}/pets/${petId}`, options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* @summary List all pets
*/
export const listPets = (params?: ListPetsParams, version = 1) => {
export const listPets = (params?: ListPetsParams, version: number = 1) => {
return customInstance<Pets>({
url: `/v${version}/pets`,
method: 'GET',
params,
});
};

export const getListPetsKey = (params?: ListPetsParams, version = 1) =>
export const getListPetsKey = (params?: ListPetsParams, version: number = 1) =>
[`/v${version}/pets`, ...(params ? [params] : [])] as const;

export type ListPetsQueryResult = NonNullable<
Expand All @@ -43,7 +43,7 @@ export type ListPetsQueryError = Error;
*/
export const useListPets = <TError = Error>(
params?: ListPetsParams,
version = 1,
version: number = 1,
options?: {
swr?: SWRConfiguration<Awaited<ReturnType<typeof listPets>>, TError> & {
swrKey?: Key;
Expand Down Expand Up @@ -74,7 +74,10 @@ export const useListPets = <TError = Error>(
/**
* @summary Create a pet
*/
export const createPets = (createPetsBody: CreatePetsBody, version = 1) => {
export const createPets = (
createPetsBody: CreatePetsBody,
version: number = 1,
) => {
return customInstance<Pet>({
url: `/v${version}/pets`,
method: 'POST',
Expand All @@ -86,14 +89,14 @@ export const createPets = (createPetsBody: CreatePetsBody, version = 1) => {
/**
* @summary Info for a specific pet
*/
export const showPetById = (petId: string, version = 1) => {
export const showPetById = (petId: string, version: number = 1) => {
return customInstance<Pet>({
url: `/v${version}/pets/${petId}`,
method: 'GET',
});
};

export const getShowPetByIdKey = (petId: string, version = 1) =>
export const getShowPetByIdKey = (petId: string, version: number = 1) =>
[`/v${version}/pets/${petId}`] as const;

export type ShowPetByIdQueryResult = NonNullable<
Expand All @@ -106,7 +109,7 @@ export type ShowPetByIdQueryError = Error;
*/
export const useShowPetById = <TError = Error>(
petId: string,
version = 1,
version: number = 1,
options?: {
swr?: SWRConfiguration<Awaited<ReturnType<typeof showPetById>>, TError> & {
swrKey?: Key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { customInstance } from '../mutator/custom-instance';
/**
* @summary List all pets
*/
export const listPets = (params?: ListPetsParams, version = 1) => {
export const listPets = (params?: ListPetsParams, version: number = 1) => {
return customInstance<Pets>({
url: `/v${version}/pets`,
method: 'GET',
Expand All @@ -21,7 +21,10 @@ export const listPets = (params?: ListPetsParams, version = 1) => {
/**
* @summary Create a pet
*/
export const createPets = (createPetsBody: CreatePetsBody, version = 1) => {
export const createPets = (
createPetsBody: CreatePetsBody,
version: number = 1,
) => {
return customInstance<void>({
url: `/v${version}/pets`,
method: 'POST',
Expand All @@ -33,7 +36,7 @@ export const createPets = (createPetsBody: CreatePetsBody, version = 1) => {
/**
* @summary Info for a specific pet
*/
export const showPetById = (petId: string, version = 1) => {
export const showPetById = (petId: string, version: number = 1) => {
return customInstance<Pet>({
url: `/v${version}/pets/${petId}`,
method: 'GET',
Expand Down
Loading