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

Define which paths can be used for queries/mutations in @kubb/plugin-react-query #1578

Open
vitalygashkov opened this issue Feb 26, 2025 · 1 comment
Labels
enhancement New feature or request

Comments

@vitalygashkov
Copy link

What is the problem this feature would solve?

As far as I know currently it is possible to split endpoints into mutations and queries only by HTTP request type (GET/POST, etc.):
https://kubb.dev/plugins/plugin-react-query/#mutation-methods

But sometimes on projects an endpoint can be a POST request, but you need to handle it as a query. And at the same time there may be other POST requests which should be like mutations.

I couldn't find a solution for this in plugin docs.

External documents/projects?

https://kubb.dev/plugins/plugin-react-query/#mutation-methods
https://kubb.dev/plugins/plugin-react-query/#query-methods

What is the feature you are proposing to solve the problem?

It would be nice to be able to override the generation of mutations and queries, for example by explicitly specifying a path.

For example, part of @kubb/plugin-react-query config:

query: {
  methods: ['get'],
  paths: ['/users'], // POST (or other mutation-like) requests to be generated as queries
  importPath: '@tanstack/react-query',
},
mutation: {
  methods: ['post', 'put', 'delete', 'patch'],
},

What alternatives have you considered?

No response

@vitalygashkov vitalygashkov added the enhancement New feature or request label Feb 26, 2025
@danielkv
Copy link

I implemented on my side a patch to test this. It worked pretty well. I added a forceInclude in the Query and Mutation options:

type Query = {
	forceInclude?: (operation: Operation) => boolean;
    /**
     * Define which HttpMethods can be used for queries
     * @default ['get']
     */
    methods: Array<HttpMethod>;
    /**
     * Path to the useQuery that will be used to do the useQuery functionality.
     * It will be used as `import { useQuery } from '${importPath}'`.
     * It allows both relative and absolute path.
     * the path will be applied as is, so relative path should be based on the file being generated.
     * @default '@tanstack/react-query'
     */
    importPath?: string;
};
type Mutation = {
	forceInclude?: (operation: Operation) => boolean;
    /**
     * Define which HttpMethods can be used for mutations
     * @default ['post', 'put', 'delete']
     */
    methods: Array<HttpMethod>;
    /**
     * Path to the useQuery that will be used to do the useQuery functionality.
     * It will be used as `import { useQuery } from '${importPath}'`.
     * It allows both relative and absolute path.
     * the path will be applied as is, so relative path should be based on the file being generated.
     * @default '@tanstack/react-query'
     */
    importPath?: string;
};

this is the patch if anyone wants to try it:

diff --git a/dist/chunk-DIM4VLBE.js b/dist/chunk-DIM4VLBE.js
index 919a2d4ebad4f252be2c28038353f34c574fb45c..4b613a02a7077809d0b8cec0766049b1c5930634 100644
--- a/dist/chunk-DIM4VLBE.js
+++ b/dist/chunk-DIM4VLBE.js
@@ -325,7 +325,8 @@ var queryGenerator = createReactGenerator({
       file: getFile(operation, { pluginKey: [pluginZodName] }),
       schemas: getSchemas(operation, { pluginKey: [pluginZodName], type: "function" })
     };
-    if (!isQuery || isMutation) {
+	const forceInclude = options.query?.forceInclude?.(operation);
+    if (!forceInclude && (!isQuery || isMutation)) {
       return null;
     }
     return /* @__PURE__ */ jsxs(
@@ -434,7 +435,8 @@ var mutationGenerator = createReactGenerator({
     } = useApp();
     const oas = useOas();
     const { getSchemas, getName, getFile } = useOperationManager();
-    const isQuery = !!options.query && options.query?.methods.some((method) => operation.method === method);
+	const forceIncludeQuery = options.query?.forceInclude?.(operation);
+    const isQuery = forceIncludeQuery || (!!options.query && options.query?.methods.some((method) => operation.method === method));
     const isMutation = !isQuery && difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method);
     const importPath = options.mutation ? options.mutation.importPath : "@tanstack/react-query";
     const mutation = {
@@ -465,7 +467,9 @@ var mutationGenerator = createReactGenerator({
       name: getName(operation, { type: "const", suffix: "MutationKey" }),
       typeName: getName(operation, { type: "type", suffix: "MutationKey" })
     };
-    if (!isMutation) {
+
+    const forceInclude = options.mutation?.forceInclude?.(operation);
+    if (!forceInclude && !isMutation) {
       return null;
     }
     return /* @__PURE__ */ jsxs(
diff --git a/dist/types-CQseu_km.d.cts b/dist/types-CQseu_km.d.cts
index e26bd56f916ea61189914c6fac195320d0207468..495c061121a93743735a3a88400c013ce2ea26d7 100644
--- a/dist/types-CQseu_km.d.cts
+++ b/dist/types-CQseu_km.d.cts
@@ -124,6 +124,7 @@ type QueryKey = Transformer;
  */
 type MutationKey = Transformer;
 type Query = {
+	forceInclude?: (operation: Operation) => boolean;
     /**
      * Define which HttpMethods can be used for queries
      * @default ['get']
@@ -139,6 +140,7 @@ type Query = {
     importPath?: string;
 };
 type Mutation = {
+	forceInclude?: (operation: Operation) => boolean;
     /**
      * Define which HttpMethods can be used for mutations
      * @default ['post', 'put', 'delete']
diff --git a/dist/types-CQseu_km.d.ts b/dist/types-CQseu_km.d.ts
index e26bd56f916ea61189914c6fac195320d0207468..495c061121a93743735a3a88400c013ce2ea26d7 100644
--- a/dist/types-CQseu_km.d.ts
+++ b/dist/types-CQseu_km.d.ts
@@ -124,6 +124,7 @@ type QueryKey = Transformer;
  */
 type MutationKey = Transformer;
 type Query = {
+	forceInclude?: (operation: Operation) => boolean;
     /**
      * Define which HttpMethods can be used for queries
      * @default ['get']
@@ -139,6 +140,7 @@ type Query = {
     importPath?: string;
 };
 type Mutation = {
+	forceInclude?: (operation: Operation) => boolean;
     /**
      * Define which HttpMethods can be used for mutations
      * @default ['post', 'put', 'delete']

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants