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

SWR: keys generated for GETs are wrapped in an array while keys for mutations are not #1487

Open
fabiendevos opened this issue Jun 27, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@fabiendevos
Copy link

fabiendevos commented Jun 27, 2024

What are the steps to reproduce this issue?

  1. Setup orval to use swr
  2. Have both a getter and a mutation
  3. Use the generated swr hooks

What happens?

useGetXxx use a key wrapped in an array ['/api/xxx'] while useCreateXxx use a string '/api/xxx'

What were you expecting to happen?

The generated keys should match for Gets and mutations.

Orval config

import { defineConfig } from 'orval';
 
 export default defineConfig({
   api: {
     input: './openapi/openapi.yaml',
     output: {
      mode: 'split',
      baseUrl: '', // Set in custom-axios.ts
      target: './openapi/api-client.ts',
      schemas: './openapi/models',
      client: 'swr',
      override: {
        mutator: {
          path: './openapi/custom-axios.ts',
          name: 'customInstance',
        },
      },
     }
   },
 });

Custom axios instance

import Axios, { AxiosRequestConfig } from 'axios';

export const AXIOS_INSTANCE = Axios.create({ baseURL: '/api' });

export const customInstance = <T>(config: AxiosRequestConfig): Promise<T> => {
  const source = Axios.CancelToken.source();
  const promise = AXIOS_INSTANCE({ ...config, cancelToken: source.token }).then(
    ({ data }) => data,
  );

  // @ts-ignore
  promise.cancel = () => {
    source.cancel('Query was cancelled.');
  };

  return promise;
};

export default customInstance;

OpenAPI yaml file

openapi: 3.1.0
info:
  title: Todo
  description: |-
    My app
  version: 0.0.1
paths:
  /tasks:
    get:
      operationId: getAllTasks
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Task'
    post:
      operationId: createTask
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Task'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
components:
  schemas:
    Task:
      type: object
      properties:
        name:
          type: string

Generated client code by Orval

Note how the key in getGetAllTasksKey is wrapped in an array but the key in getCreateTaskMutationKey isn't.

/**
 * Generated by orval v6.31.0 🍺
 * Do not edit manually.
 * Todo
 * My app
 * OpenAPI spec version: 0.0.1
 */
import useSwr from 'swr'
import type {
  Key,
  SWRConfiguration
} from 'swr'
import useSWRMutation from 'swr/mutation'
import type {
  SWRMutationConfiguration
} from 'swr/mutation'
import type {
  Task
} from './models'
import { customInstance } from './custom-axios';


  
  export const getAllTasks = (
    
 ) => {
      return customInstance<Task[]>(
      {url: `/tasks`, method: 'GET'
    },
      );
    }
  


export const getGetAllTasksKey = () => [`/tasks`] as const;


export type GetAllTasksQueryResult = NonNullable<Awaited<ReturnType<typeof getAllTasks>>>
export type GetAllTasksQueryError = unknown

export const useGetAllTasks = <TError = unknown>(
   options?: { swr?:SWRConfiguration<Awaited<ReturnType<typeof getAllTasks>>, TError> & { swrKey?: Key, enabled?: boolean },  }
) => {
  const {swr: swrOptions} = options ?? {}

  const isEnabled = swrOptions?.enabled !== false
  const swrKey = swrOptions?.swrKey ?? (() => isEnabled ? getGetAllTasksKey() : null);
  const swrFn = () => getAllTasks();

  const query = useSwr<Awaited<ReturnType<typeof swrFn>>, TError>(swrKey, swrFn, swrOptions)

  return {
    swrKey,
    ...query
  }
}

export const createTask = (
    task: Task,
 ) => {
      return customInstance<Task>(
      {url: `/tasks`, method: 'POST',
      headers: {'Content-Type': 'application/json', },
      data: task
    },
      );
    }
  


export const getCreateTaskMutationFetcher = ( ) => {
  return (_: string, { arg }: { arg: Task }): Promise<Task> => {
    return createTask(arg);
  }
}
export const getCreateTaskMutationKey = () => `/tasks` as const;

export type CreateTaskMutationResult = NonNullable<Awaited<ReturnType<typeof createTask>>>
export type CreateTaskMutationError = unknown

export const useCreateTask = <TError = unknown>(
   options?: { swr?:SWRMutationConfiguration<Awaited<ReturnType<typeof createTask>>, TError, string, Task, Awaited<ReturnType<typeof createTask>>> & { swrKey?: string },  }
) => {

  const {swr: swrOptions} = options ?? {}

  const swrKey = swrOptions?.swrKey ?? getCreateTaskMutationKey();
  const swrFn = getCreateTaskMutationFetcher();

  const query = useSWRMutation(swrKey, swrFn, swrOptions)

  return {
    swrKey,
    ...query
  }
}

What versions are you using?

Operating System: macOS Sonoma 14.3
Package Version: orval 6.30.2, swr 2.2.5, axios 1.7.2
Browser Version: Chrome Version 125.0.6422.142

@melloware melloware added the bug Something isn't working label Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants