orval-labs / orval

orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in yaml or json formats. 🍺
https://orval.dev
MIT License
2.8k stars 311 forks source link

[Regression in 0.30] Using useQuery: true for POST request generates code that does not compile #1447

Open severinh opened 2 months ago

severinh commented 2 months ago

What are the steps to reproduce this issue?

  1. Have an Orval project with client: 'react-query', and using Orval 0.30.X+
  2. Have a POST method that should be output as a query, not as a mutation We need POST because it requires a large request body (path parameters don't work for it).
  3. In orval.config.ts, set override.operations.project_aggregation_query.query.useQuery to true.
  4. Since orval 0.30, orval outputs code that does not compile. Concretely, the generated useProjectAggregationQueryQueryOptions now passes a signal parameter to projectAggregationQuery, but projectAggregationQuery does not actually accept a signal parameter.
export const projectAggregationQuery = (
  projectId: string,
  aggregationInputInput: AggregationInputInput,
  options?: SecondParameter<typeof instance>,
  // --------------
  // BUG: This function is missing the signal parameter
  // --------------
) => {
  return instance<AggregationResult>(
    {
      url: `/data/analytics/projects/${projectId}/aggregation`,
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      data: aggregationInputInput,
    },
    options
  );
};

export const getProjectAggregationQueryQueryKey = (projectId: string, aggregationInputInput: AggregationInputInput) => {
  return [`/data/analytics/projects/${projectId}/aggregation`, aggregationInputInput] as const;
};

export const useProjectAggregationQueryQueryOptions = <
  TData = Awaited<ReturnType<typeof projectAggregationQuery>>,
  TError = ErrorType<HTTPValidationError>,
>(
  projectId: string,
  aggregationInputInput: AggregationInputInput,
  options?: {
    query?: UseQueryOptions<Awaited<ReturnType<typeof projectAggregationQuery>>, TError, TData>;
    request?: SecondParameter<typeof instance>;
  }
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey = queryOptions?.queryKey ?? getProjectAggregationQueryQueryKey(projectId, aggregationInputInput);

  const queryFn: QueryFunction<Awaited<ReturnType<typeof projectAggregationQuery>>> = ({ signal }) =>
    // --------------
    // BUG: Here we get the compilation failure. It complains that projectAggregationQuery only support 2-3 parameters, not 4.
    // --------------
    projectAggregationQuery(projectId, aggregationInputInput, requestOptions, signal);

  const customOptions = useDefaultOpenApiQueryOptions({ ...queryOptions, queryKey, queryFn });

  return customOptions as UseQueryOptions<Awaited<ReturnType<typeof projectAggregationQuery>>, TError, TData> & {
    queryKey: QueryKey;
  };
};

What happens?

The code generated by Orval does not compile. useProjectAggregationQueryQueryOptions now passes a signal parameter to projectAggregationQuery, but projectAggregationQuery does not actually accept a signal parameter.

What were you expecting to happen?

The generated projectAggregationQuery should have a signal parameter.

Any logs, error output, etc?

N/A

Any other comments?

This is a new regression. It did not happen in 0.29.x. In 0.29.x, neither projectAggregationQuery also did not have a signal parameter, but also useProjectAggregationQueryQueryOptions did not pass one.

Here's our orval.config.ts:

  analytics: {
    input: {
      target: '../../generated-schemas/analytics.json',
    },
    output: {
      mode: 'split',
      target: 'src/generated',
      client: 'react-query',
      override: {
        mutator: defaultMutator,
        operations: {
          project_aggregation_query: {
            query: {
              // This is a POST request, since it requires a request body, but is actually a query, not a mutation.
              // This forces Orval to generate a query instead of a mutation hook.
              useQuery: true,
            },
          },
        },
      },
    },
  },

We found a work-around: We now pass signal: false to the override. This restores the behavior in 0.29.x, and lets the code compile successfully. However, it's not ideal. This means that this query cannot be aborted properly by react-query.

What versions are you using?

Operating System: MacOS (but bug is independent from it) Package Version: 0.30.2 Browser Version: N/A

severinh commented 2 months ago

Actually, this bug is related to https://github.com/anymaniax/orval/issues/1434:

Most likely, the fix to properly support abort signals for POST queries will close both of these issues.

melloware commented 2 months ago

@severinh any help or PR would be appreciated!