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

using the group option to group zod schemas causes imported path mistakes in react-query hooks file #1483

Open
QingjiaTsang opened this issue Dec 21, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@QingjiaTsang
Copy link

What version of kubb is running?

3.3.4

What kind of platform do you use?

MacOS

How does your kubb.config.ts config look like

import { defineConfig } from '@kubb/core';
import { pluginOas } from '@kubb/plugin-oas';
import { pluginReactQuery } from '@kubb/plugin-react-query';
import { QueryKey } from '@kubb/plugin-react-query/components';
import { pluginTs } from '@kubb/plugin-ts';
import { pluginZod } from '@kubb/plugin-zod';
import { pluginFaker } from '@kubb/plugin-faker';
import { pluginMsw } from '@kubb/plugin-msw';

/** @type {import('@kubb/core').UserConfig} */
export const config = {
  root: '.',
  input: {
    path: './openapi.json',
  },
  output: {
    path: './src/gen',
    clean: true,
  },
  hooks: {
    done: ['bun typecheck'],
  },
  plugins: [
    pluginOas({ generators: [] }),
    pluginTs({
      output: {
        path: 'models',
      },
    }),
    pluginZod({
      output: {
        path: './zod',
      },
      // This group option would cause problems
      group: { type: 'tag', name: ({ group }) => `${group}Schemas` },
      dateType: 'date',
      unknownType: 'unknown',
      inferred: true,
    }),
    pluginReactQuery({
      client: {
        baseURL: '/api',
        // custom axios client for interceptors
        importPath: '@/lib/customAxiosClient',
      },
      transformers: {
        name: (name, type) => {
          if (type === 'file' || type === 'function') {
            return `${name}Hook`;
          }
          return name;
        },
      },
      output: {
        path: './hooks/api',
      },
      group: {
        type: 'path',
      },
      queryKey(props) {
        const keys = QueryKey.getTransformer(props);
        return ['"v5"', ...keys];
      },
      paramsType: 'inline',
      pathParamsType: 'object',
      suspense: {},
      override: [
        {
          type: 'operationId',
          pattern: 'listTasks',
          options: {
            infinite: {
              queryParam: 'page',
              initialPageParam: 1,
              cursorParam: undefined,
            },
          },
        },
      ],
      parser: 'zod',
    }),

    pluginFaker({
      output: {
        path: './mocks',
      },
      group: {
        type: 'tag',
        name: ({ group }) => `${group}Mocks`,
      },
    }),

    pluginMsw({
      output: {
        path: './mocks/msw',
      },
      group: {
        type: 'tag',
        name: ({ group }) => `${group}Handlers`,
      },
      parser: 'faker',
    }),
  ],
};

export default defineConfig(config);

Swagger/OpenAPI file?

{
  "openapi": "3.0.0",
  "info": {
    "version": "1.0.0",
    "title": "Tasks API"
  },
  "components": {
    "schemas": {},
    "parameters": {}
  },
  "paths": {
    "/": {
      "get": {
        "tags": ["Index"],
        "operationId": "lists",
        "responses": {
          "200": {
            "description": "Tasks API Index",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": ["message"],
                  "example": {
                    "message": "Tasks API"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tasks": {
      "get": {
        "tags": ["Tasks"],
        "operationId": "listTasks",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "The list of tasks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "minimum": 0,
                            "exclusiveMinimum": true
                          },
                          "name": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 500
                          },
                          "done": {
                            "type": "boolean"
                          },
                          "createdAt": {
                            "type": "string",
                            "nullable": true
                          },
                          "updatedAt": {
                            "type": "string",
                            "nullable": true
                          }
                        },
                        "required": ["id", "name", "done", "createdAt", "updatedAt"]
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "page": {
                      "type": "integer",
                      "minimum": 0,
                      "exclusiveMinimum": true
                    },
                    "pageSize": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "totalPages": {
                      "type": "integer",
                      "minimum": 0
                    }
                  },
                  "required": ["data", "total", "page", "pageSize", "totalPages"]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Tasks"],
        "operationId": "createTask",
        "requestBody": {
          "description": "The task to create",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "done": {
                    "type": "boolean"
                  }
                },
                "required": ["name", "done"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created task",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer",
                      "minimum": 0,
                      "exclusiveMinimum": true
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "done": {
                      "type": "boolean"
                    },
                    "createdAt": {
                      "type": "string",
                      "nullable": true
                    },
                    "updatedAt": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": ["id", "name", "done", "createdAt", "updatedAt"]
                }
              }
            }
          },
          "422": {
            "description": "The validation error(s)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "issues": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "path": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                }
                              },
                              "message": {
                                "type": "string"
                              }
                            },
                            "required": ["code", "path"]
                          }
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["issues", "name"],
                      "example": {
                        "issues": [
                          {
                            "code": "invalid_type",
                            "expected": "string",
                            "received": "undefined",
                            "path": ["name"],
                            "message": "Required"
                          },
                          {
                            "code": "invalid_type",
                            "expected": "boolean",
                            "received": "undefined",
                            "path": ["done"],
                            "message": "Required"
                          }
                        ],
                        "name": "ZodError"
                      }
                    }
                  },
                  "required": ["success", "error"]
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}": {
      "get": {
        "tags": ["Tasks"],
        "operationId": "getTaskById",
        "parameters": [
          {
            "schema": {
              "type": "number",
              "nullable": true,
              "required": ["id"],
              "example": 42
            },
            "required": false,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The requested task",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer",
                      "minimum": 0,
                      "exclusiveMinimum": true
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "done": {
                      "type": "boolean"
                    },
                    "createdAt": {
                      "type": "string",
                      "nullable": true
                    },
                    "updatedAt": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": ["id", "name", "done", "createdAt", "updatedAt"]
                }
              }
            }
          },
          "404": {
            "description": "Task not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": ["message"],
                  "example": {
                    "message": "Not Found"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Invalid id error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "issues": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "path": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                }
                              },
                              "message": {
                                "type": "string"
                              }
                            },
                            "required": ["code", "path"]
                          }
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["issues", "name"],
                      "example": {
                        "issues": [
                          {
                            "code": "invalid_type",
                            "expected": "number",
                            "received": "nan",
                            "path": ["id"],
                            "message": "Expected number, received nan"
                          }
                        ],
                        "name": "ZodError"
                      }
                    }
                  },
                  "required": ["success", "error"]
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Tasks"],
        "operationId": "updateTaskById",
        "parameters": [
          {
            "schema": {
              "type": "number",
              "nullable": true,
              "required": ["id"],
              "example": 42
            },
            "required": false,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "description": "The task updates",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "done": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated task",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer",
                      "minimum": 0,
                      "exclusiveMinimum": true
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "done": {
                      "type": "boolean"
                    },
                    "createdAt": {
                      "type": "string",
                      "nullable": true
                    },
                    "updatedAt": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": ["id", "name", "done", "createdAt", "updatedAt"]
                }
              }
            }
          },
          "404": {
            "description": "Task not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": ["message"],
                  "example": {
                    "message": "Not Found"
                  }
                }
              }
            }
          },
          "422": {
            "description": "The validation error(s)",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "example": false
                        },
                        "error": {
                          "type": "object",
                          "properties": {
                            "issues": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "code": {
                                    "type": "string"
                                  },
                                  "path": {
                                    "type": "array",
                                    "items": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "number"
                                        }
                                      ]
                                    }
                                  },
                                  "message": {
                                    "type": "string"
                                  }
                                },
                                "required": ["code", "path"]
                              }
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": ["issues", "name"]
                        }
                      },
                      "required": ["success", "error"]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "example": false
                        },
                        "error": {
                          "type": "object",
                          "properties": {
                            "issues": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "code": {
                                    "type": "string"
                                  },
                                  "path": {
                                    "type": "array",
                                    "items": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "number"
                                        }
                                      ]
                                    }
                                  },
                                  "message": {
                                    "type": "string"
                                  }
                                },
                                "required": ["code", "path"]
                              }
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": ["issues", "name"],
                          "example": {
                            "issues": [
                              {
                                "code": "invalid_type",
                                "expected": "number",
                                "received": "nan",
                                "path": ["id"],
                                "message": "Expected number, received nan"
                              }
                            ],
                            "name": "ZodError"
                          }
                        }
                      },
                      "required": ["success", "error"]
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Tasks"],
        "operationId": "deleteTaskById",
        "parameters": [
          {
            "schema": {
              "type": "number",
              "nullable": true,
              "required": ["id"],
              "example": 42
            },
            "required": false,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "204": {
            "description": "Task deleted"
          },
          "404": {
            "description": "Task not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": ["message"],
                  "example": {
                    "message": "Not Found"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Invalid id error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "issues": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "path": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                }
                              },
                              "message": {
                                "type": "string"
                              }
                            },
                            "required": ["code", "path"]
                          }
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": ["issues", "name"],
                      "example": {
                        "issues": [
                          {
                            "code": "invalid_type",
                            "expected": "number",
                            "received": "nan",
                            "path": ["id"],
                            "message": "Expected number, received nan"
                          }
                        ],
                        "name": "ZodError"
                      }
                    }
                  },
                  "required": ["success", "error"]
                }
              }
            }
          }
        }
      }
    }
  }
}

What version of external packages are you using(@tanstack-query, MSW, React, Vue, ...)

{
  "name": "react-ts-kubb-demo",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview",
    "generate": "kubb generate",
    "typecheck": "tsc --noEmit",
    "format": "prettier --write \"src/**/*.{ts,tsx,md,json}\""
  },
  "dependencies": {
    "@kubb/plugin-oas": "^3.3.4",
    "@kubb/plugin-ts": "^3.3.4",
    "@kubb/react": "^3.3.4",
    "@tanstack/react-query": "^5.62.8",
    "@tanstack/react-query-devtools": "^5.62.8",
    "ajv": "^8.17.1",
    "axios": "^1.7.9",
    "path": "^0.12.7",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@eslint/js": "^9.17.0",
    "@faker-js/faker": "^9.3.0",
    "@kubb/cli": "^3.3.4",
    "@kubb/core": "^3.3.4",
    "@kubb/plugin-client": "^3.3.4",
    "@kubb/plugin-faker": "^3.3.4",
    "@kubb/plugin-msw": "^3.3.4",
    "@kubb/plugin-react-query": "^3.3.4",
    "@types/node": "^22.10.2",
    "@types/react": "^18.3.17",
    "@types/react-dom": "^18.3.5",
    "@vitejs/plugin-react": "^4.3.4",
    "autoprefixer": "^10.4.20",
    "eslint": "^9.17.0",
    "eslint-plugin-react-hooks": "^5.0.0",
    "eslint-plugin-react-refresh": "^0.4.16",
    "globals": "^15.13.0",
    "msw": "^2.7.0",
    "postcss": "^8.4.49",
    "tailwindcss": "^3.4.17",
    "tsx": "^4.19.2",
    "typescript": "~5.6.2",
    "typescript-eslint": "^8.18.1",
    "vite": "^6.0.3",
    "vite-plugin-checker": "^0.8.0"
  },
  "msw": {
    "workerDirectory": [
      "public"
    ]
  }
}

What steps can reproduce the bug?

  1. set the group option:
image
  1. click into the react-query hooks file after runing the generation cli and you'll see the wrong import path there which exists in every react-query hooks files:
image

How often does this bug happen?

Every time

What is the expected behavior?

No response

Additional information

No response

@QingjiaTsang QingjiaTsang added the bug Something isn't working label Dec 21, 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

1 participant