From 505487582667fb2d9fe99a25ad53ea608ce5033d Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 11 Aug 2024 00:41:26 +0100 Subject: [PATCH] docs: add TanStack React Query example --- .changeset/hungry-apples-grab.md | 5 + examples/openapi-ts-axios/src/App.css | 15 - examples/openapi-ts-axios/src/App.tsx | 8 +- examples/openapi-ts-fetch/src/App.css | 15 - examples/openapi-ts-fetch/src/App.tsx | 8 +- .../.gitignore | 24 + .../index.html | 13 + .../openapi-ts.config.ts | 18 + .../package.json | 42 ++ .../postcss.config.js | 6 + .../src/App.css | 3 + .../src/App.tsx | 278 ++++++++ .../src/client/@tanstack/react-query.gen.ts | 503 +++++++++++++++ .../src/client/index.ts | 4 + .../src/client/schemas.gen.ts | 244 ++++++++ .../src/client/services.gen.ts | 337 ++++++++++ .../src/client/types.gen.ts | 591 ++++++++++++++++++ .../src/main.tsx | 28 + .../src/vite-env.d.ts | 1 + .../tailwind.config.js | 8 + .../tsconfig.json | 25 + .../tsconfig.node.json | 11 + .../vite.config.ts | 7 + packages/openapi-ts/package.json | 2 +- pnpm-lock.yaml | 191 +++++- 25 files changed, 2342 insertions(+), 45 deletions(-) create mode 100644 .changeset/hungry-apples-grab.md create mode 100644 examples/openapi-ts-tanstack-react-query/.gitignore create mode 100644 examples/openapi-ts-tanstack-react-query/index.html create mode 100644 examples/openapi-ts-tanstack-react-query/openapi-ts.config.ts create mode 100644 examples/openapi-ts-tanstack-react-query/package.json create mode 100644 examples/openapi-ts-tanstack-react-query/postcss.config.js create mode 100644 examples/openapi-ts-tanstack-react-query/src/App.css create mode 100644 examples/openapi-ts-tanstack-react-query/src/App.tsx create mode 100644 examples/openapi-ts-tanstack-react-query/src/client/@tanstack/react-query.gen.ts create mode 100644 examples/openapi-ts-tanstack-react-query/src/client/index.ts create mode 100644 examples/openapi-ts-tanstack-react-query/src/client/schemas.gen.ts create mode 100644 examples/openapi-ts-tanstack-react-query/src/client/services.gen.ts create mode 100644 examples/openapi-ts-tanstack-react-query/src/client/types.gen.ts create mode 100644 examples/openapi-ts-tanstack-react-query/src/main.tsx create mode 100644 examples/openapi-ts-tanstack-react-query/src/vite-env.d.ts create mode 100644 examples/openapi-ts-tanstack-react-query/tailwind.config.js create mode 100644 examples/openapi-ts-tanstack-react-query/tsconfig.json create mode 100644 examples/openapi-ts-tanstack-react-query/tsconfig.node.json create mode 100644 examples/openapi-ts-tanstack-react-query/vite.config.ts diff --git a/.changeset/hungry-apples-grab.md b/.changeset/hungry-apples-grab.md new file mode 100644 index 000000000..e168ee93d --- /dev/null +++ b/.changeset/hungry-apples-grab.md @@ -0,0 +1,5 @@ +--- +'@example/openapi-ts-tanstack-react-query': patch +--- + +docs: add TanStack React Query example diff --git a/examples/openapi-ts-axios/src/App.css b/examples/openapi-ts-axios/src/App.css index 7f28c560b..b5c61c956 100644 --- a/examples/openapi-ts-axios/src/App.css +++ b/examples/openapi-ts-axios/src/App.css @@ -1,18 +1,3 @@ @tailwind base; @tailwind components; @tailwind utilities; - -.logo { - height: 4em; - will-change: filter; - transition: filter 300ms; -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/examples/openapi-ts-axios/src/App.tsx b/examples/openapi-ts-axios/src/App.tsx index 5c8d794cb..7039cabe3 100644 --- a/examples/openapi-ts-axios/src/App.tsx +++ b/examples/openapi-ts-axios/src/App.tsx @@ -147,10 +147,14 @@ function App() {
- + Hey API logo diff --git a/examples/openapi-ts-fetch/src/App.css b/examples/openapi-ts-fetch/src/App.css index 7f28c560b..b5c61c956 100644 --- a/examples/openapi-ts-fetch/src/App.css +++ b/examples/openapi-ts-fetch/src/App.css @@ -1,18 +1,3 @@ @tailwind base; @tailwind components; @tailwind utilities; - -.logo { - height: 4em; - will-change: filter; - transition: filter 300ms; -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/examples/openapi-ts-fetch/src/App.tsx b/examples/openapi-ts-fetch/src/App.tsx index d6217617d..c3f291903 100644 --- a/examples/openapi-ts-fetch/src/App.tsx +++ b/examples/openapi-ts-fetch/src/App.tsx @@ -147,10 +147,14 @@ function App() {
- + Hey API logo diff --git a/examples/openapi-ts-tanstack-react-query/.gitignore b/examples/openapi-ts-tanstack-react-query/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/openapi-ts-tanstack-react-query/index.html b/examples/openapi-ts-tanstack-react-query/index.html new file mode 100644 index 000000000..6f15b3d0a --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/index.html @@ -0,0 +1,13 @@ + + + + + + + Hey API + TanStack React Query Demo + + +
+ + + diff --git a/examples/openapi-ts-tanstack-react-query/openapi-ts.config.ts b/examples/openapi-ts-tanstack-react-query/openapi-ts.config.ts new file mode 100644 index 000000000..2aa9e83f4 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/openapi-ts.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from '@hey-api/openapi-ts'; + +export default defineConfig({ + client: '@hey-api/client-fetch', + input: + 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml', + // 'https://raw.githubusercontent.com/Redocly/museum-openapi-example/main/openapi.yaml', + // '../../packages/openapi-ts/test/spec/v3.json', + output: { + format: 'prettier', + lint: 'eslint', + path: './src/client', + }, + plugins: ['@tanstack/react-query'], + types: { + enums: 'javascript', + }, +}); diff --git a/examples/openapi-ts-tanstack-react-query/package.json b/examples/openapi-ts-tanstack-react-query/package.json new file mode 100644 index 000000000..da716d68a --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/package.json @@ -0,0 +1,42 @@ +{ + "name": "@example/openapi-ts-tanstack-react-query", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "build": "tsc && vite build", + "dev": "vite", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "openapi-ts": "openapi-ts", + "preview": "vite preview", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@hey-api/client-fetch": "workspace:*", + "@radix-ui/react-form": "0.1.0", + "@radix-ui/react-icons": "1.3.0", + "@radix-ui/themes": "3.1.1", + "@tanstack/react-query": "5.51.23", + "@tanstack/react-query-devtools": "5.51.23", + "react": "18.3.1", + "react-dom": "18.3.1" + }, + "devDependencies": { + "@hey-api/openapi-ts": "workspace:*", + "@tanstack/eslint-plugin-query": "5.51.15", + "@types/react": "18.3.3", + "@types/react-dom": "18.3.0", + "@typescript-eslint/eslint-plugin": "7.15.0", + "@typescript-eslint/parser": "7.15.0", + "@vitejs/plugin-react": "4.3.1", + "autoprefixer": "10.4.19", + "eslint": "9.6.0", + "eslint-plugin-react-hooks": "4.6.2", + "eslint-plugin-react-refresh": "0.4.7", + "postcss": "8.4.39", + "prettier": "3.3.2", + "tailwindcss": "3.4.4", + "typescript": "5.5.3", + "vite": "5.3.3" + } +} diff --git a/examples/openapi-ts-tanstack-react-query/postcss.config.js b/examples/openapi-ts-tanstack-react-query/postcss.config.js new file mode 100644 index 000000000..9eef821c4 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + autoprefixer: {}, + tailwindcss: {}, + }, +}; diff --git a/examples/openapi-ts-tanstack-react-query/src/App.css b/examples/openapi-ts-tanstack-react-query/src/App.css new file mode 100644 index 000000000..b5c61c956 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/App.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/examples/openapi-ts-tanstack-react-query/src/App.tsx b/examples/openapi-ts-tanstack-react-query/src/App.tsx new file mode 100644 index 000000000..59b21c021 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/App.tsx @@ -0,0 +1,278 @@ +import './App.css'; + +import { createClient } from '@hey-api/client-fetch'; +import * as Form from '@radix-ui/react-form'; +import { DownloadIcon, PlusIcon, ReloadIcon } from '@radix-ui/react-icons'; +import { + Avatar, + Box, + Button, + Card, + Container, + Flex, + Heading, + Section, + Text, + TextField, +} from '@radix-ui/themes'; +import { useMutation, useQuery } from '@tanstack/react-query'; +import { useEffect, useState } from 'react'; + +import { + addPetMutation, + getPetByIdOptions, + updatePetMutation, +} from './client/@tanstack/react-query.gen'; +import { $Pet } from './client/schemas.gen'; +import { client } from './client/services.gen'; +import type { Pet } from './client/types.gen'; + +// configure internal service client +client.setConfig({ + // set default base url for requests + baseUrl: 'https://petstore3.swagger.io/api/v3', + // set default headers for requests + headers: { + Authorization: 'Bearer ', + }, +}); + +const localClient = createClient({ + // set default base url for requests made by this client + baseUrl: 'https://petstore3.swagger.io/api/v3', + /** + * Set default headers only for requests made by this client. This is to + * demonstrate local clients and their configuration taking precedence over + * internal service client. + */ + headers: { + Authorization: 'Bearer ', + }, +}); + +localClient.interceptors.request.use((request, options) => { + // Middleware is great for adding authorization tokens to requests made to + // protected paths. Headers are set randomly here to allow surfacing the + // default headers, too. + if ( + options.url === '/pet/{petId}' && + options.method === 'GET' && + Math.random() < 0.5 + ) { + request.headers.set('Authorization', 'Bearer '); + } + return request; +}); + +function App() { + const [pet, setPet] = useState(); + const [petId, setPetId] = useState(); + const [isRequiredNameError, setIsRequiredNameError] = useState(false); + + const addPet = useMutation({ + ...addPetMutation, + onError: (error) => { + console.log(error); + setIsRequiredNameError(false); + }, + onSuccess: (data) => { + setPet(data); + setIsRequiredNameError(false); + }, + }); + + const updatePet = useMutation({ + ...updatePetMutation, + onError: (error) => { + console.log(error); + }, + onSuccess: (data) => { + setPet(data); + }, + }); + + const { data, error } = useQuery({ + ...getPetByIdOptions({ + client: localClient, + path: { + petId: petId!, + }, + }), + enabled: Boolean(petId), + }); + + const onAddPet = async (formData: FormData) => { + // simple form field validation to demonstrate using schemas + if ($Pet.required.includes('name') && !formData.get('name')) { + setIsRequiredNameError(true); + return; + } + + addPet.mutate({ + body: { + category: { + id: 0, + name: formData.get('category') as string, + }, + id: 0, + name: formData.get('name') as string, + photoUrls: ['string'], + status: 'available', + tags: [ + { + id: 0, + name: 'string', + }, + ], + }, + }); + }; + + const onGetPetById = async () => { + // random id 1-10 + setPetId(Math.floor(Math.random() * (10 - 1 + 1) + 1)); + }; + + const onUpdatePet = async () => { + updatePet.mutate({ + body: { + category: { + id: 0, + name: 'Cats', + }, + id: 2, + name: 'Updated Kitty', + photoUrls: ['string'], + status: 'available', + tags: [ + { + id: 0, + name: 'string', + }, + ], + }, + // setting headers per request + headers: { + Authorization: 'Bearer ', + }, + }); + }; + + useEffect(() => { + if (error) { + console.log(error); + return; + } + setPet(data!); + }, [data, error]); + + return ( + + +
+ + + Hey API logo + + @hey-api/openapi-ts 🤝 TanStack React Query + +
+ + + + + + + + Name: {pet?.name ?? 'N/A'} + + + Category: {pet?.category?.name ?? 'N/A'} + + + + + + + +
+ + { + event.preventDefault(); + onAddPet(new FormData(event.currentTarget)); + }} + > + +
+ + Name + + {isRequiredNameError && ( + + Please enter a name + + )} +
+ + + +
+ +
+ + Category + + + Please enter a category + +
+ + + +
+ + + + + + +
+
+
+ + + ); +} + +export default App; diff --git a/examples/openapi-ts-tanstack-react-query/src/client/@tanstack/react-query.gen.ts b/examples/openapi-ts-tanstack-react-query/src/client/@tanstack/react-query.gen.ts new file mode 100644 index 000000000..b4ee5eba1 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/client/@tanstack/react-query.gen.ts @@ -0,0 +1,503 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Options } from '@hey-api/client-fetch'; +import { + type DefaultError, + queryOptions, + type UseMutationOptions, +} from '@tanstack/react-query'; + +import { + addPet, + createUser, + createUsersWithListInput, + deleteOrder, + deletePet, + deleteUser, + findPetsByStatus, + findPetsByTags, + getInventory, + getOrderById, + getPetById, + getUserByName, + loginUser, + logoutUser, + placeOrder, + updatePet, + updatePetWithForm, + updateUser, + uploadFile, +} from '../services.gen'; +import type { + AddPetData, + AddPetError, + AddPetResponse, + CreateUserData, + CreateUserError, + CreateUserResponse, + CreateUsersWithListInputData, + CreateUsersWithListInputError, + CreateUsersWithListInputResponse, + DeleteOrderData, + DeletePetData, + DeleteUserData, + FindPetsByStatusData, + FindPetsByTagsData, + GetOrderByIdData, + GetPetByIdData, + GetUserByNameData, + LoginUserData, + PlaceOrderData, + PlaceOrderError, + PlaceOrderResponse, + UpdatePetData, + UpdatePetError, + UpdatePetResponse, + UpdatePetWithFormData, + UpdateUserData, + UpdateUserError, + UpdateUserResponse, + UploadFileData, + UploadFileError, + UploadFileResponse, +} from '../types.gen'; + +type QueryKey = [ + { + infinite?: boolean; + params: Pick; + scope: string; + }, +]; + +const createQueryKeyParams = ( + options?: TOptions, +): QueryKey[0]['params'] => { + const params: QueryKey[0]['params'] = + {} as QueryKey[0]['params']; + if (options?.body) { + params.body = options.body; + } + if (options?.headers) { + params.headers = options.headers; + } + if (options?.path) { + params.path = options.path; + } + if (options?.query) { + params.query = options.query; + } + return params; +}; + +export const addPetOptions = (options: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await addPet({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'addPet', + }, + ], + }); + +export const addPetMutation: UseMutationOptions< + AddPetResponse, + AddPetError, + Options +> = { + mutationFn: async (options) => { + const { data } = await addPet({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const updatePetMutation: UseMutationOptions< + UpdatePetResponse, + UpdatePetError, + Options +> = { + mutationFn: async (options) => { + const { data } = await updatePet({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const findPetsByStatusOptions = ( + options?: Options, +) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await findPetsByStatus({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'findPetsByStatus', + }, + ], + }); + +export const findPetsByTagsOptions = (options?: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await findPetsByTags({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'findPetsByTags', + }, + ], + }); + +export const getPetByIdOptions = (options: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await getPetById({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'getPetById', + }, + ], + }); + +export const updatePetWithFormOptions = ( + options: Options, +) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await updatePetWithForm({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'updatePetWithForm', + }, + ], + }); + +export const updatePetWithFormMutation: UseMutationOptions< + void, + DefaultError, + Options +> = { + mutationFn: async (options) => { + const { data } = await updatePetWithForm({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const deletePetMutation: UseMutationOptions< + void, + DefaultError, + Options +> = { + mutationFn: async (options) => { + const { data } = await deletePet({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const uploadFileOptions = (options: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await uploadFile({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'uploadFile', + }, + ], + }); + +export const uploadFileMutation: UseMutationOptions< + UploadFileResponse, + UploadFileError, + Options +> = { + mutationFn: async (options) => { + const { data } = await uploadFile({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const getInventoryOptions = (options?: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await getInventory({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'getInventory', + }, + ], + }); + +export const placeOrderOptions = (options?: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await placeOrder({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'placeOrder', + }, + ], + }); + +export const placeOrderMutation: UseMutationOptions< + PlaceOrderResponse, + PlaceOrderError, + Options +> = { + mutationFn: async (options) => { + const { data } = await placeOrder({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const getOrderByIdOptions = (options: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await getOrderById({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'getOrderById', + }, + ], + }); + +export const deleteOrderMutation: UseMutationOptions< + void, + DefaultError, + Options +> = { + mutationFn: async (options) => { + const { data } = await deleteOrder({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const createUserOptions = (options?: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await createUser({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'createUser', + }, + ], + }); + +export const createUserMutation: UseMutationOptions< + CreateUserResponse, + CreateUserError, + Options +> = { + mutationFn: async (options) => { + const { data } = await createUser({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const createUsersWithListInputOptions = ( + options?: Options, +) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await createUsersWithListInput({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'createUsersWithListInput', + }, + ], + }); + +export const createUsersWithListInputMutation: UseMutationOptions< + CreateUsersWithListInputResponse, + CreateUsersWithListInputError, + Options +> = { + mutationFn: async (options) => { + const { data } = await createUsersWithListInput({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const loginUserOptions = (options?: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await loginUser({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'loginUser', + }, + ], + }); + +export const logoutUserOptions = (options?: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await logoutUser({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'logoutUser', + }, + ], + }); + +export const getUserByNameOptions = (options: Options) => + queryOptions({ + queryFn: async ({ queryKey }) => { + const { data } = await getUserByName({ + ...options, + ...queryKey[0].params, + throwOnError: true, + }); + return data; + }, + queryKey: [ + { + params: createQueryKeyParams(options), + scope: 'getUserByName', + }, + ], + }); + +export const updateUserMutation: UseMutationOptions< + UpdateUserResponse, + UpdateUserError, + Options +> = { + mutationFn: async (options) => { + const { data } = await updateUser({ + ...options, + throwOnError: true, + }); + return data; + }, +}; + +export const deleteUserMutation: UseMutationOptions< + void, + DefaultError, + Options +> = { + mutationFn: async (options) => { + const { data } = await deleteUser({ + ...options, + throwOnError: true, + }); + return data; + }, +}; diff --git a/examples/openapi-ts-tanstack-react-query/src/client/index.ts b/examples/openapi-ts-tanstack-react-query/src/client/index.ts new file mode 100644 index 000000000..002afc333 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/client/index.ts @@ -0,0 +1,4 @@ +// This file is auto-generated by @hey-api/openapi-ts +export * from './schemas.gen'; +export * from './services.gen'; +export * from './types.gen'; diff --git a/examples/openapi-ts-tanstack-react-query/src/client/schemas.gen.ts b/examples/openapi-ts-tanstack-react-query/src/client/schemas.gen.ts new file mode 100644 index 000000000..8f6b9dc92 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/client/schemas.gen.ts @@ -0,0 +1,244 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export const $Order = { + properties: { + complete: { + type: 'boolean', + }, + id: { + example: 10, + format: 'int64', + type: 'integer', + }, + petId: { + example: 198772, + format: 'int64', + type: 'integer', + }, + quantity: { + example: 7, + format: 'int32', + type: 'integer', + }, + shipDate: { + format: 'date-time', + type: 'string', + }, + status: { + description: 'Order Status', + enum: ['placed', 'approved', 'delivered'], + example: 'approved', + type: 'string', + }, + }, + type: 'object', + 'x-swagger-router-model': 'io.swagger.petstore.model.Order', + xml: { + name: 'order', + }, +} as const; + +export const $Customer = { + properties: { + address: { + items: { + $ref: '#/components/schemas/Address', + }, + type: 'array', + xml: { + name: 'addresses', + wrapped: true, + }, + }, + id: { + example: 100000, + format: 'int64', + type: 'integer', + }, + username: { + example: 'fehguy', + type: 'string', + }, + }, + type: 'object', + xml: { + name: 'customer', + }, +} as const; + +export const $Address = { + properties: { + city: { + example: 'Palo Alto', + type: 'string', + }, + state: { + example: 'CA', + type: 'string', + }, + street: { + example: '437 Lytton', + type: 'string', + }, + zip: { + example: 94301, + type: 'string', + }, + }, + type: 'object', + xml: { + name: 'address', + }, +} as const; + +export const $Category = { + properties: { + id: { + example: 1, + format: 'int64', + type: 'integer', + }, + name: { + example: 'Dogs', + type: 'string', + }, + }, + type: 'object', + 'x-swagger-router-model': 'io.swagger.petstore.model.Category', + xml: { + name: 'category', + }, +} as const; + +export const $User = { + properties: { + email: { + example: 'john@email.com', + type: 'string', + }, + firstName: { + example: 'John', + type: 'string', + }, + id: { + example: 10, + format: 'int64', + type: 'integer', + }, + lastName: { + example: 'James', + type: 'string', + }, + password: { + example: 12345, + type: 'string', + }, + phone: { + example: 12345, + type: 'string', + }, + userStatus: { + description: 'User Status', + example: 1, + format: 'int32', + type: 'integer', + }, + username: { + example: 'theUser', + type: 'string', + }, + }, + type: 'object', + 'x-swagger-router-model': 'io.swagger.petstore.model.User', + xml: { + name: 'user', + }, +} as const; + +export const $Tag = { + properties: { + id: { + format: 'int64', + type: 'integer', + }, + name: { + type: 'string', + }, + }, + type: 'object', + 'x-swagger-router-model': 'io.swagger.petstore.model.Tag', + xml: { + name: 'tag', + }, +} as const; + +export const $Pet = { + properties: { + category: { + $ref: '#/components/schemas/Category', + }, + id: { + example: 10, + format: 'int64', + type: 'integer', + }, + name: { + example: 'doggie', + type: 'string', + }, + photoUrls: { + items: { + type: 'string', + xml: { + name: 'photoUrl', + }, + }, + type: 'array', + xml: { + wrapped: true, + }, + }, + status: { + description: 'pet status in the store', + enum: ['available', 'pending', 'sold'], + type: 'string', + }, + tags: { + items: { + $ref: '#/components/schemas/Tag', + xml: { + name: 'tag', + }, + }, + type: 'array', + xml: { + wrapped: true, + }, + }, + }, + required: ['name', 'photoUrls'], + type: 'object', + 'x-swagger-router-model': 'io.swagger.petstore.model.Pet', + xml: { + name: 'pet', + }, +} as const; + +export const $ApiResponse = { + properties: { + code: { + format: 'int32', + type: 'integer', + }, + message: { + type: 'string', + }, + type: { + type: 'string', + }, + }, + type: 'object', + xml: { + name: '##default', + }, +} as const; diff --git a/examples/openapi-ts-tanstack-react-query/src/client/services.gen.ts b/examples/openapi-ts-tanstack-react-query/src/client/services.gen.ts new file mode 100644 index 000000000..d495ca284 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/client/services.gen.ts @@ -0,0 +1,337 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { + createClient, + createConfig, + type Options, +} from '@hey-api/client-fetch'; + +import type { + AddPetData, + AddPetError, + AddPetResponse, + CreateUserData, + CreateUserError, + CreateUserResponse, + CreateUsersWithListInputData, + CreateUsersWithListInputError, + CreateUsersWithListInputResponse, + DeleteOrderData, + DeletePetData, + DeleteUserData, + FindPetsByStatusData, + FindPetsByStatusError, + FindPetsByStatusResponse, + FindPetsByTagsData, + FindPetsByTagsError, + FindPetsByTagsResponse, + GetInventoryError, + GetInventoryResponse, + GetOrderByIdData, + GetOrderByIdError, + GetOrderByIdResponse, + GetPetByIdData, + GetPetByIdError, + GetPetByIdResponse, + GetUserByNameData, + GetUserByNameError, + GetUserByNameResponse, + LoginUserData, + LoginUserError, + LoginUserResponse, + LogoutUserError, + LogoutUserResponse, + PlaceOrderData, + PlaceOrderError, + PlaceOrderResponse, + UpdatePetData, + UpdatePetError, + UpdatePetResponse, + UpdatePetWithFormData, + UpdateUserData, + UpdateUserError, + UpdateUserResponse, + UploadFileData, + UploadFileError, + UploadFileResponse, +} from './types.gen'; + +export const client = createClient(createConfig()); + +/** + * Add a new pet to the store + * Add a new pet to the store + */ +export const addPet = ( + options: Options, +) => + (options?.client ?? client).post({ + ...options, + url: '/pet', + }); + +/** + * Update an existing pet + * Update an existing pet by Id + */ +export const updatePet = ( + options: Options, +) => + (options?.client ?? client).put< + UpdatePetResponse, + UpdatePetError, + ThrowOnError + >({ + ...options, + url: '/pet', + }); + +/** + * Finds Pets by status + * Multiple status values can be provided with comma separated strings + */ +export const findPetsByStatus = ( + options?: Options, +) => + (options?.client ?? client).get< + FindPetsByStatusResponse, + FindPetsByStatusError, + ThrowOnError + >({ + ...options, + url: '/pet/findByStatus', + }); + +/** + * Finds Pets by tags + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + */ +export const findPetsByTags = ( + options?: Options, +) => + (options?.client ?? client).get< + FindPetsByTagsResponse, + FindPetsByTagsError, + ThrowOnError + >({ + ...options, + url: '/pet/findByTags', + }); + +/** + * Find pet by ID + * Returns a single pet + */ +export const getPetById = ( + options: Options, +) => + (options?.client ?? client).get< + GetPetByIdResponse, + GetPetByIdError, + ThrowOnError + >({ + ...options, + url: '/pet/{petId}', + }); + +/** + * Updates a pet in the store with form data + */ +export const updatePetWithForm = ( + options: Options, +) => + (options?.client ?? client).post({ + ...options, + url: '/pet/{petId}', + }); + +/** + * Deletes a pet + */ +export const deletePet = ( + options: Options, +) => + (options?.client ?? client).delete({ + ...options, + url: '/pet/{petId}', + }); + +/** + * uploads an image + */ +export const uploadFile = ( + options: Options, +) => + (options?.client ?? client).post< + UploadFileResponse, + UploadFileError, + ThrowOnError + >({ + ...options, + url: '/pet/{petId}/uploadImage', + }); + +/** + * Returns pet inventories by status + * Returns a map of status codes to quantities + */ +export const getInventory = ( + options?: Options, +) => + (options?.client ?? client).get< + GetInventoryResponse, + GetInventoryError, + ThrowOnError + >({ + ...options, + url: '/store/inventory', + }); + +/** + * Place an order for a pet + * Place a new order in the store + */ +export const placeOrder = ( + options?: Options, +) => + (options?.client ?? client).post< + PlaceOrderResponse, + PlaceOrderError, + ThrowOnError + >({ + ...options, + url: '/store/order', + }); + +/** + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions. + */ +export const getOrderById = ( + options: Options, +) => + (options?.client ?? client).get< + GetOrderByIdResponse, + GetOrderByIdError, + ThrowOnError + >({ + ...options, + url: '/store/order/{orderId}', + }); + +/** + * Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + */ +export const deleteOrder = ( + options: Options, +) => + (options?.client ?? client).delete({ + ...options, + url: '/store/order/{orderId}', + }); + +/** + * Create user + * This can only be done by the logged in user. + */ +export const createUser = ( + options?: Options, +) => + (options?.client ?? client).post< + CreateUserResponse, + CreateUserError, + ThrowOnError + >({ + ...options, + url: '/user', + }); + +/** + * Creates list of users with given input array + * Creates list of users with given input array + */ +export const createUsersWithListInput = ( + options?: Options, +) => + (options?.client ?? client).post< + CreateUsersWithListInputResponse, + CreateUsersWithListInputError, + ThrowOnError + >({ + ...options, + url: '/user/createWithList', + }); + +/** + * Logs user into the system + */ +export const loginUser = ( + options?: Options, +) => + (options?.client ?? client).get< + LoginUserResponse, + LoginUserError, + ThrowOnError + >({ + ...options, + url: '/user/login', + }); + +/** + * Logs out current logged in user session + */ +export const logoutUser = ( + options?: Options, +) => + (options?.client ?? client).get< + LogoutUserResponse, + LogoutUserError, + ThrowOnError + >({ + ...options, + url: '/user/logout', + }); + +/** + * Get user by user name + */ +export const getUserByName = ( + options: Options, +) => + (options?.client ?? client).get< + GetUserByNameResponse, + GetUserByNameError, + ThrowOnError + >({ + ...options, + url: '/user/{username}', + }); + +/** + * Update user + * This can only be done by the logged in user. + */ +export const updateUser = ( + options: Options, +) => + (options?.client ?? client).put< + UpdateUserResponse, + UpdateUserError, + ThrowOnError + >({ + ...options, + url: '/user/{username}', + }); + +/** + * Delete user + * This can only be done by the logged in user. + */ +export const deleteUser = ( + options: Options, +) => + (options?.client ?? client).delete({ + ...options, + url: '/user/{username}', + }); diff --git a/examples/openapi-ts-tanstack-react-query/src/client/types.gen.ts b/examples/openapi-ts-tanstack-react-query/src/client/types.gen.ts new file mode 100644 index 000000000..19df2b8b3 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/client/types.gen.ts @@ -0,0 +1,591 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type Order = { + complete?: boolean; + id?: number; + petId?: number; + quantity?: number; + shipDate?: string; + /** + * Order Status + */ + status?: 'placed' | 'approved' | 'delivered'; +}; + +/** + * Order Status + */ +export type status = 'placed' | 'approved' | 'delivered'; + +/** + * Order Status + */ +export const status = { + APPROVED: 'approved', + DELIVERED: 'delivered', + PLACED: 'placed', +} as const; + +export type Customer = { + address?: Array
; + id?: number; + username?: string; +}; + +export type Address = { + city?: string; + state?: string; + street?: string; + zip?: string; +}; + +export type Category = { + id?: number; + name?: string; +}; + +export type User = { + email?: string; + firstName?: string; + id?: number; + lastName?: string; + password?: string; + phone?: string; + /** + * User Status + */ + userStatus?: number; + username?: string; +}; + +export type Tag = { + id?: number; + name?: string; +}; + +export type Pet = { + category?: Category; + id?: number; + name: string; + photoUrls: Array; + /** + * pet status in the store + */ + status?: 'available' | 'pending' | 'sold'; + tags?: Array; +}; + +/** + * pet status in the store + */ +export type status2 = 'available' | 'pending' | 'sold'; + +/** + * pet status in the store + */ +export const status2 = { + AVAILABLE: 'available', + PENDING: 'pending', + SOLD: 'sold', +} as const; + +export type ApiResponse = { + code?: number; + message?: string; + type?: string; +}; + +export type AddPetData = { + /** + * Create a new pet in the store + */ + body: Pet; +}; + +export type AddPetResponse = Pet; + +export type AddPetError = unknown; + +export type UpdatePetData = { + /** + * Update an existent pet in the store + */ + body: Pet; +}; + +export type UpdatePetResponse = Pet; + +export type UpdatePetError = unknown; + +export type FindPetsByStatusData = { + query?: { + /** + * Status values that need to be considered for filter + */ + status?: 'available' | 'pending' | 'sold'; + }; +}; + +export type FindPetsByStatusResponse = Array; + +export type FindPetsByStatusError = unknown; + +export type FindPetsByTagsData = { + query?: { + /** + * Tags to filter by + */ + tags?: Array; + }; +}; + +export type FindPetsByTagsResponse = Array; + +export type FindPetsByTagsError = unknown; + +export type GetPetByIdData = { + path: { + /** + * ID of pet to return + */ + petId: number; + }; +}; + +export type GetPetByIdResponse = Pet; + +export type GetPetByIdError = unknown; + +export type UpdatePetWithFormData = { + path: { + /** + * ID of pet that needs to be updated + */ + petId: number; + }; + query?: { + /** + * Name of pet that needs to be updated + */ + name?: string; + /** + * Status of pet that needs to be updated + */ + status?: string; + }; +}; + +export type DeletePetData = { + headers?: { + api_key?: string; + }; + path: { + /** + * Pet id to delete + */ + petId: number; + }; +}; + +export type UploadFileData = { + body?: Blob | File; + path: { + /** + * ID of pet to update + */ + petId: number; + }; + query?: { + /** + * Additional Metadata + */ + additionalMetadata?: string; + }; +}; + +export type UploadFileResponse = ApiResponse; + +export type UploadFileError = unknown; + +export type GetInventoryResponse = { + [key: string]: number; +}; + +export type GetInventoryError = unknown; + +export type PlaceOrderData = { + body?: Order; +}; + +export type PlaceOrderResponse = Order; + +export type PlaceOrderError = unknown; + +export type GetOrderByIdData = { + path: { + /** + * ID of order that needs to be fetched + */ + orderId: number; + }; +}; + +export type GetOrderByIdResponse = Order; + +export type GetOrderByIdError = unknown; + +export type DeleteOrderData = { + path: { + /** + * ID of the order that needs to be deleted + */ + orderId: number; + }; +}; + +export type CreateUserData = { + /** + * Created user object + */ + body?: User; +}; + +export type CreateUserResponse = User; + +export type CreateUserError = unknown; + +export type CreateUsersWithListInputData = { + body?: Array; +}; + +export type CreateUsersWithListInputResponse = User | unknown; + +export type CreateUsersWithListInputError = unknown; + +export type LoginUserData = { + query?: { + /** + * The password for login in clear text + */ + password?: string; + /** + * The user name for login + */ + username?: string; + }; +}; + +export type LoginUserResponse = string; + +export type LoginUserError = unknown; + +export type LogoutUserResponse = unknown; + +export type LogoutUserError = unknown; + +export type GetUserByNameData = { + path: { + /** + * The name that needs to be fetched. Use user1 for testing. + */ + username: string; + }; +}; + +export type GetUserByNameResponse = User; + +export type GetUserByNameError = unknown; + +export type UpdateUserData = { + /** + * Update an existent user in the store + */ + body?: User; + path: { + /** + * name that needs to be updated + */ + username: string; + }; +}; + +export type UpdateUserResponse = unknown; + +export type UpdateUserError = unknown; + +export type DeleteUserData = { + path: { + /** + * The name that needs to be deleted + */ + username: string; + }; +}; + +export type $OpenApiTs = { + '/pet': { + post: { + req: AddPetData; + res: { + /** + * Successful operation + */ + '200': Pet; + /** + * Invalid input + */ + '405': unknown; + }; + }; + put: { + req: UpdatePetData; + res: { + /** + * Successful operation + */ + '200': Pet; + /** + * Invalid ID supplied + */ + '400': unknown; + /** + * Pet not found + */ + '404': unknown; + /** + * Validation exception + */ + '405': unknown; + }; + }; + }; + '/pet/findByStatus': { + get: { + req: FindPetsByStatusData; + res: { + /** + * successful operation + */ + '200': Array; + /** + * Invalid status value + */ + '400': unknown; + }; + }; + }; + '/pet/findByTags': { + get: { + req: FindPetsByTagsData; + res: { + /** + * successful operation + */ + '200': Array; + /** + * Invalid tag value + */ + '400': unknown; + }; + }; + }; + '/pet/{petId}': { + delete: { + req: DeletePetData; + res: { + /** + * Invalid pet value + */ + '400': unknown; + }; + }; + get: { + req: GetPetByIdData; + res: { + /** + * successful operation + */ + '200': Pet; + /** + * Invalid ID supplied + */ + '400': unknown; + /** + * Pet not found + */ + '404': unknown; + }; + }; + post: { + req: UpdatePetWithFormData; + res: { + /** + * Invalid input + */ + '405': unknown; + }; + }; + }; + '/pet/{petId}/uploadImage': { + post: { + req: UploadFileData; + res: { + /** + * successful operation + */ + '200': ApiResponse; + }; + }; + }; + '/store/inventory': { + get: { + res: { + /** + * successful operation + */ + '200': { + [key: string]: number; + }; + }; + }; + }; + '/store/order': { + post: { + req: PlaceOrderData; + res: { + /** + * successful operation + */ + '200': Order; + /** + * Invalid input + */ + '405': unknown; + }; + }; + }; + '/store/order/{orderId}': { + delete: { + req: DeleteOrderData; + res: { + /** + * Invalid ID supplied + */ + '400': unknown; + /** + * Order not found + */ + '404': unknown; + }; + }; + get: { + req: GetOrderByIdData; + res: { + /** + * successful operation + */ + '200': Order; + /** + * Invalid ID supplied + */ + '400': unknown; + /** + * Order not found + */ + '404': unknown; + }; + }; + }; + '/user': { + post: { + req: CreateUserData; + res: { + /** + * successful operation + */ + default: User; + }; + }; + }; + '/user/createWithList': { + post: { + req: CreateUsersWithListInputData; + res: { + /** + * Successful operation + */ + '200': User; + /** + * successful operation + */ + default: unknown; + }; + }; + }; + '/user/login': { + get: { + req: LoginUserData; + res: { + /** + * successful operation + */ + '200': string; + /** + * Invalid username/password supplied + */ + '400': unknown; + }; + }; + }; + '/user/logout': { + get: { + res: { + /** + * successful operation + */ + default: unknown; + }; + }; + }; + '/user/{username}': { + delete: { + req: DeleteUserData; + res: { + /** + * Invalid username supplied + */ + '400': unknown; + /** + * User not found + */ + '404': unknown; + }; + }; + get: { + req: GetUserByNameData; + res: { + /** + * successful operation + */ + '200': User; + /** + * Invalid username supplied + */ + '400': unknown; + /** + * User not found + */ + '404': unknown; + }; + }; + put: { + req: UpdateUserData; + res: { + /** + * successful operation + */ + default: unknown; + }; + }; + }; +}; diff --git a/examples/openapi-ts-tanstack-react-query/src/main.tsx b/examples/openapi-ts-tanstack-react-query/src/main.tsx new file mode 100644 index 000000000..94fbb689b --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/main.tsx @@ -0,0 +1,28 @@ +import '@radix-ui/themes/styles.css'; + +import { Theme } from '@radix-ui/themes'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import React from 'react'; +import ReactDOM from 'react-dom/client'; + +import App from './App.tsx'; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: 60000, + }, + }, +}); + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + + + + , +); diff --git a/examples/openapi-ts-tanstack-react-query/src/vite-env.d.ts b/examples/openapi-ts-tanstack-react-query/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/openapi-ts-tanstack-react-query/tailwind.config.js b/examples/openapi-ts-tanstack-react-query/tailwind.config.js new file mode 100644 index 000000000..0284c5614 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./index.html', './src/**/*.{html,js,ts,jsx,tsx}'], + plugins: [], + theme: { + extend: {}, + }, +}; diff --git a/examples/openapi-ts-tanstack-react-query/tsconfig.json b/examples/openapi-ts-tanstack-react-query/tsconfig.json new file mode 100644 index 000000000..a7fc6fbf2 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/examples/openapi-ts-tanstack-react-query/tsconfig.node.json b/examples/openapi-ts-tanstack-react-query/tsconfig.node.json new file mode 100644 index 000000000..97ede7ee6 --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/examples/openapi-ts-tanstack-react-query/vite.config.ts b/examples/openapi-ts-tanstack-react-query/vite.config.ts new file mode 100644 index 000000000..4e7004ebc --- /dev/null +++ b/examples/openapi-ts-tanstack-react-query/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react'; +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}); diff --git a/packages/openapi-ts/package.json b/packages/openapi-ts/package.json index e5a4fc080..3f2b6f38e 100644 --- a/packages/openapi-ts/package.json +++ b/packages/openapi-ts/package.json @@ -85,7 +85,7 @@ "@hey-api/client-fetch": "workspace:*", "@rollup/plugin-json": "6.1.0", "@rollup/plugin-node-resolve": "15.2.3", - "@tanstack/react-query": "5.51.11", + "@tanstack/react-query": "5.51.23", "@types/cross-spawn": "6.0.6", "@types/express": "4.17.21", "axios": "1.7.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f14095e54..fe92e9521 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -222,6 +222,82 @@ importers: specifier: 5.3.3 version: 5.3.3(@types/node@20.14.10)(less@4.2.0)(sass@1.71.1)(terser@5.31.1) + examples/openapi-ts-tanstack-react-query: + dependencies: + '@hey-api/client-fetch': + specifier: workspace:* + version: link:../../packages/client-fetch + '@radix-ui/react-form': + specifier: 0.1.0 + version: 0.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-icons': + specifier: 1.3.0 + version: 1.3.0(react@18.3.1) + '@radix-ui/themes': + specifier: 3.1.1 + version: 3.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tanstack/react-query': + specifier: 5.51.23 + version: 5.51.23(react@18.3.1) + '@tanstack/react-query-devtools': + specifier: 5.51.23 + version: 5.51.23(@tanstack/react-query@5.51.23(react@18.3.1))(react@18.3.1) + react: + specifier: 18.3.1 + version: 18.3.1 + react-dom: + specifier: 18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@hey-api/openapi-ts': + specifier: workspace:* + version: link:../../packages/openapi-ts + '@tanstack/eslint-plugin-query': + specifier: 5.51.15 + version: 5.51.15(eslint@9.6.0)(typescript@5.5.3) + '@types/react': + specifier: 18.3.3 + version: 18.3.3 + '@types/react-dom': + specifier: 18.3.0 + version: 18.3.0 + '@typescript-eslint/eslint-plugin': + specifier: 7.15.0 + version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/parser': + specifier: 7.15.0 + version: 7.15.0(eslint@9.6.0)(typescript@5.5.3) + '@vitejs/plugin-react': + specifier: 4.3.1 + version: 4.3.1(vite@5.3.3(@types/node@20.14.10)(less@4.2.0)(sass@1.71.1)(terser@5.31.1)) + autoprefixer: + specifier: 10.4.19 + version: 10.4.19(postcss@8.4.39) + eslint: + specifier: 9.6.0 + version: 9.6.0 + eslint-plugin-react-hooks: + specifier: 4.6.2 + version: 4.6.2(eslint@9.6.0) + eslint-plugin-react-refresh: + specifier: 0.4.7 + version: 0.4.7(eslint@9.6.0) + postcss: + specifier: 8.4.39 + version: 8.4.39 + prettier: + specifier: 3.3.2 + version: 3.3.2 + tailwindcss: + specifier: 3.4.4 + version: 3.4.4(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)) + typescript: + specifier: 5.5.3 + version: 5.5.3 + vite: + specifier: 5.3.3 + version: 5.3.3(@types/node@20.14.10)(less@4.2.0)(sass@1.71.1)(terser@5.31.1) + packages/client-axios: devDependencies: axios: @@ -296,8 +372,8 @@ importers: specifier: 15.2.3 version: 15.2.3(rollup@4.18.0) '@tanstack/react-query': - specifier: 5.51.11 - version: 5.51.11(react@18.3.1) + specifier: 5.51.23 + version: 5.51.23(react@18.3.1) '@types/cross-spawn': specifier: 6.0.6 version: 6.0.6 @@ -2629,11 +2705,25 @@ packages: '@stackblitz/sdk@1.11.0': resolution: {integrity: sha512-DFQGANNkEZRzFk1/rDP6TcFdM82ycHE+zfl9C/M/jXlH68jiqHWHFMQURLELoD8koxvu/eW5uhg94NSAZlYrUQ==} - '@tanstack/query-core@5.51.9': - resolution: {integrity: sha512-HsAwaY5J19MD18ykZDS3aVVh+bAt0i7m6uQlFC2b77DLV9djo+xEN7MWQAQQTR8IM+7r/zbozTQ7P0xr0bHuew==} + '@tanstack/eslint-plugin-query@5.51.15': + resolution: {integrity: sha512-btX03EOGvNxTGJDqHMmQwfSt/hp93Z8I4FNBijoyEdDnjGi4jVjpGP7nEi9LaMnHFsylucptVGb6GQngWs07bA==} + peerDependencies: + eslint: ^8 || ^9 + + '@tanstack/query-core@5.51.21': + resolution: {integrity: sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw==} + + '@tanstack/query-devtools@5.51.16': + resolution: {integrity: sha512-ajwuq4WnkNCMj/Hy3KR8d3RtZ6PSKc1dD2vs2T408MdjgKzQ3klVoL6zDgVO7X+5jlb5zfgcO3thh4ojPhfIaw==} + + '@tanstack/react-query-devtools@5.51.23': + resolution: {integrity: sha512-XpHrdyfUPGULIyJ1K7UvhAcK+KjMJdw4NjmRjryoj3XEgfAU5qU1rz8gIFvGc3gTGT07yIseGo7GEll/ICfJfQ==} + peerDependencies: + '@tanstack/react-query': ^5.51.23 + react: ^18 || ^19 - '@tanstack/react-query@5.51.11': - resolution: {integrity: sha512-4Kq2x0XpDlpvSnaLG+8pHNH60zEc3mBvb3B2tOMDjcPCi/o+Du3p/9qpPLwJOTliVxxPJAP27fuIhLrsRdCr7A==} + '@tanstack/react-query@5.51.23': + resolution: {integrity: sha512-CfJCfX45nnVIZjQBRYYtvVMIsGgWLKLYC4xcUiYEey671n1alvTZoCBaU9B85O8mF/tx9LPyrI04A6Bs2THv4A==} peerDependencies: react: ^18.0.0 @@ -2818,6 +2908,10 @@ packages: resolution: {integrity: sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@8.0.0-alpha.30': + resolution: {integrity: sha512-FGW/iPWGyPFamAVZ60oCAthMqQrqafUGebF8UKuq/ha+e9SVG6YhJoRzurlQXOVf8dHfOhJ0ADMXyFnMc53clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/type-utils@7.15.0': resolution: {integrity: sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2836,6 +2930,10 @@ packages: resolution: {integrity: sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/types@8.0.0-alpha.30': + resolution: {integrity: sha512-4WzLlw27SO9pK9UFj/Hu7WGo8WveT0SEiIpFVsV2WwtQmLps6kouwtVCB8GJPZKJyurhZhcqCoQVQFmpv441Vg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@5.62.0': resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2854,6 +2952,15 @@ packages: typescript: optional: true + '@typescript-eslint/typescript-estree@8.0.0-alpha.30': + resolution: {integrity: sha512-WSXbc9ZcXI+7yC+6q95u77i8FXz6HOLsw3ST+vMUlFy1lFbXyFL/3e6HDKQCm2Clt0krnoCPiTGvIn+GkYPn4Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/utils@5.62.0': resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2866,6 +2973,12 @@ packages: peerDependencies: eslint: ^8.56.0 + '@typescript-eslint/utils@8.0.0-alpha.30': + resolution: {integrity: sha512-rfhqfLqFyXhHNDwMnHiVGxl/Z2q/3guQ1jLlGQ0hi9Rb7inmwz42crM+NnLPR+2vEnwyw1P/g7fnQgQ3qvFx4g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/visitor-keys@5.62.0': resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2874,6 +2987,10 @@ packages: resolution: {integrity: sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/visitor-keys@8.0.0-alpha.30': + resolution: {integrity: sha512-XZuNurZxBqmr6ZIRIwWFq7j5RZd6ZlkId/HZEWyfciK+CWoyOxSF9Pv2VXH9Rlu2ZG2PfbhLz2Veszl4Pfn7yA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vitejs/plugin-basic-ssl@1.1.0': resolution: {integrity: sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==} engines: {node: '>=14.6.0'} @@ -9303,11 +9420,27 @@ snapshots: '@stackblitz/sdk@1.11.0': {} - '@tanstack/query-core@5.51.9': {} + '@tanstack/eslint-plugin-query@5.51.15(eslint@9.6.0)(typescript@5.5.3)': + dependencies: + '@typescript-eslint/utils': 8.0.0-alpha.30(eslint@9.6.0)(typescript@5.5.3) + eslint: 9.6.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@tanstack/query-core@5.51.21': {} - '@tanstack/react-query@5.51.11(react@18.3.1)': + '@tanstack/query-devtools@5.51.16': {} + + '@tanstack/react-query-devtools@5.51.23(@tanstack/react-query@5.51.23(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/query-devtools': 5.51.16 + '@tanstack/react-query': 5.51.23(react@18.3.1) + react: 18.3.1 + + '@tanstack/react-query@5.51.23(react@18.3.1)': dependencies: - '@tanstack/query-core': 5.51.9 + '@tanstack/query-core': 5.51.21 react: 18.3.1 '@tootallnate/quickjs-emscripten@0.23.0': {} @@ -9531,6 +9664,11 @@ snapshots: '@typescript-eslint/types': 7.15.0 '@typescript-eslint/visitor-keys': 7.15.0 + '@typescript-eslint/scope-manager@8.0.0-alpha.30': + dependencies: + '@typescript-eslint/types': 8.0.0-alpha.30 + '@typescript-eslint/visitor-keys': 8.0.0-alpha.30 + '@typescript-eslint/type-utils@7.15.0(eslint@9.6.0)(typescript@5.5.3)': dependencies: '@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3) @@ -9547,6 +9685,8 @@ snapshots: '@typescript-eslint/types@7.15.0': {} + '@typescript-eslint/types@8.0.0-alpha.30': {} + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.5.3)': dependencies: '@typescript-eslint/types': 5.62.0 @@ -9576,6 +9716,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.0.0-alpha.30(typescript@5.5.3)': + dependencies: + '@typescript-eslint/types': 8.0.0-alpha.30 + '@typescript-eslint/visitor-keys': 8.0.0-alpha.30 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@5.62.0(eslint@9.6.0)(typescript@5.5.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) @@ -9602,6 +9757,17 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@8.0.0-alpha.30(eslint@9.6.0)(typescript@5.5.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) + '@typescript-eslint/scope-manager': 8.0.0-alpha.30 + '@typescript-eslint/types': 8.0.0-alpha.30 + '@typescript-eslint/typescript-estree': 8.0.0-alpha.30(typescript@5.5.3) + eslint: 9.6.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/visitor-keys@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -9612,6 +9778,11 @@ snapshots: '@typescript-eslint/types': 7.15.0 eslint-visitor-keys: 3.4.3 + '@typescript-eslint/visitor-keys@8.0.0-alpha.30': + dependencies: + '@typescript-eslint/types': 8.0.0-alpha.30 + eslint-visitor-keys: 3.4.3 + '@vitejs/plugin-basic-ssl@1.1.0(vite@5.1.7(@types/node@20.14.10)(less@4.2.0)(sass@1.71.1)(terser@5.29.1))': dependencies: vite: 5.1.7(@types/node@20.14.10)(less@4.2.0)(sass@1.71.1)(terser@5.29.1) @@ -11499,7 +11670,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/parser': 7.24.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 -- 2.51.2