diff --git a/package.json b/package.json index a2aaf7a..755d5e8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build": "next build", "start": "next start", "lint": "next lint", - "generate-client": "openapi-ts && prettier --write ./src/client/**/*.ts && git add ./src/client" + "generate-client": "openapi-ts && prettier --write ./src/lib/client/**/*.ts && git add ./src/lib/client" }, "dependencies": { "@dnd-kit/core": "^6.3.1", diff --git a/src/app/deals/components/shared/Header/Header.tsx b/src/app/deals/components/shared/Header/Header.tsx index 2ecb858..c2b6eec 100644 --- a/src/app/deals/components/shared/Header/Header.tsx +++ b/src/app/deals/components/shared/Header/Header.tsx @@ -11,8 +11,12 @@ import { ColorSchemeToggle } from "@/components/ui/ColorSchemeToggle/ColorScheme import useIsMobile from "@/hooks/useIsMobile"; const Header = () => { - const { projects, setSelectedProject, selectedProject } = - useProjectsContext(); + const { + projects, + setSelectedProject, + selectedProject, + setIsEditorDrawerOpened: setIsProjectsDrawerOpened, + } = useProjectsContext(); const { setIsEditorDrawerOpened } = useBoardsContext(); const isMobile = useIsMobile(); @@ -38,7 +42,9 @@ const Header = () => { return ( - + setIsProjectsDrawerOpened(true)}> {selectedProject?.name} diff --git a/src/app/deals/contexts/ProjectsContext.tsx b/src/app/deals/contexts/ProjectsContext.tsx index 4cdcc2d..ec3da88 100644 --- a/src/app/deals/contexts/ProjectsContext.tsx +++ b/src/app/deals/contexts/ProjectsContext.tsx @@ -7,8 +7,9 @@ import React, { useEffect, useState, } from "react"; -import { ProjectSchema } from "@/lib/client"; import useProjectsList from "@/hooks/useProjectsList"; +import { useProjectsOperations } from "@/hooks/useProjectsOperations"; +import { ProjectSchema, UpdateProjectSchema } from "@/lib/client"; type ProjectsContextState = { selectedProject: ProjectSchema | null; @@ -16,6 +17,11 @@ type ProjectsContextState = { React.SetStateAction >; projects: ProjectSchema[]; + onCreateProject: (name: string) => void; + onUpdateProject: (projectId: number, project: UpdateProjectSchema) => void; + onDeleteProject: (project: ProjectSchema) => void; + isEditorDrawerOpened: boolean; + setIsEditorDrawerOpened: React.Dispatch>; }; const ProjectsContext = createContext( @@ -23,7 +29,13 @@ const ProjectsContext = createContext( ); const useProjectsContextState = () => { - const { projects } = useProjectsList(); + const [isEditorDrawerOpened, setIsEditorDrawerOpened] = + useState(false); + const { + projects, + setProjects, + refetch: refetchProjects, + } = useProjectsList(); const [selectedProject, setSelectedProject] = useState(null); @@ -43,10 +55,22 @@ const useProjectsContextState = () => { setSelectedProject(null); }, [projects]); + const { onCreateProject, onUpdateProject, onDeleteProject } = + useProjectsOperations({ + projects, + setProjects, + refetchProjects, + }); + return { projects, selectedProject, setSelectedProject, + onCreateProject, + onUpdateProject, + onDeleteProject, + isEditorDrawerOpened, + setIsEditorDrawerOpened, }; }; diff --git a/src/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer.module.css b/src/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer.module.css new file mode 100644 index 0000000..8d9f762 --- /dev/null +++ b/src/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer.module.css @@ -0,0 +1,15 @@ +.project:hover { + background-color: whitesmoke; + + @mixin dark { + background-color: var(--mantine-color-dark-6); + } +} + +.menu-button { + cursor: pointer; +} + +.project:hover:has(.menu-button:hover) { + background: none; /* or revert to normal */ +} diff --git a/src/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer.tsx b/src/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer.tsx new file mode 100644 index 0000000..94b465f --- /dev/null +++ b/src/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer.tsx @@ -0,0 +1,66 @@ +"use client"; + +import React, { FC } from "react"; +import { IconChevronLeft } from "@tabler/icons-react"; +import { + Box, + Center, + Divider, + Drawer, + Group, + rem, + Stack, + Text, +} from "@mantine/core"; +import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; +import CreateProjectButton from "@/app/deals/drawers/ProjectsEditorDrawer/components/CreateProjectButton"; +import ProjectMobile from "@/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMobile"; + +const ProjectsEditorDrawer: FC = () => { + const { projects, isEditorDrawerOpened, setIsEditorDrawerOpened } = + useProjectsContext(); + const onClose = () => setIsEditorDrawerOpened(false); + + return ( + + + + + +
+ Проекты +
+ +
+ + + {projects.map((project, index) => ( + + ))} + + +
+ ); +}; + +export default ProjectsEditorDrawer; diff --git a/src/app/deals/drawers/ProjectsEditorDrawer/components/CreateProjectButton.tsx b/src/app/deals/drawers/ProjectsEditorDrawer/components/CreateProjectButton.tsx new file mode 100644 index 0000000..b7b9e90 --- /dev/null +++ b/src/app/deals/drawers/ProjectsEditorDrawer/components/CreateProjectButton.tsx @@ -0,0 +1,32 @@ +import { IconPlus } from "@tabler/icons-react"; +import { Box, Group, Text } from "@mantine/core"; +import { modals } from "@mantine/modals"; +import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; + +const CreateProjectButton = () => { + const { onCreateProject } = useProjectsContext(); + + const onStartCreating = () => { + modals.openContextModal({ + modal: "enterNameModal", + title: "Создание проекта", + withCloseButton: true, + innerProps: { + onComplete: onCreateProject, + }, + }); + }; + + return ( + + + + Создать проект + + + ); +}; + +export default CreateProjectButton; diff --git a/src/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMenu.tsx b/src/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMenu.tsx new file mode 100644 index 0000000..7023bf2 --- /dev/null +++ b/src/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMenu.tsx @@ -0,0 +1,56 @@ +import React, { FC } from "react"; +import { IconDotsVertical, IconEdit, IconTrash } from "@tabler/icons-react"; +import { Box, Group, Menu, Text } from "@mantine/core"; +import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; +import { ProjectSchema } from "@/lib/client"; +import styles from "./../ProjectsEditorDrawer.module.css"; + +type Props = { + project: ProjectSchema; + startEditing: () => void; + menuIconSize: number; +}; + +const ProjectMenu: FC = ({ + project, + startEditing, + menuIconSize = 16, +}) => { + const { onDeleteProject } = useProjectsContext(); + + return ( + + + e.stopPropagation()}> + + + + + { + e.stopPropagation(); + startEditing(); + }}> + + + Переименовать + + + { + e.stopPropagation(); + onDeleteProject(project); + }}> + + + Удалить + + + + + ); +}; + +export default ProjectMenu; diff --git a/src/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMobile.tsx b/src/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMobile.tsx new file mode 100644 index 0000000..4e90774 --- /dev/null +++ b/src/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMobile.tsx @@ -0,0 +1,55 @@ +import React, { FC } from "react"; +import { Box, Group, Text } from "@mantine/core"; +import { modals } from "@mantine/modals"; +import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; +import ProjectMenu from "@/app/deals/drawers/ProjectsEditorDrawer/components/ProjectMenu"; +import { ProjectSchema } from "@/lib/client"; +import styles from "./../ProjectsEditorDrawer.module.css"; + +type Props = { + project: ProjectSchema; +}; + +const ProjectMobile: FC = ({ project }) => { + const { onUpdateProject, setSelectedProject, setIsEditorDrawerOpened } = + useProjectsContext(); + + const startEditing = () => { + modals.openContextModal({ + modal: "enterNameModal", + title: "Редактирование проекта", + withCloseButton: true, + innerProps: { + onComplete: name => onUpdateProject(project.id, { name }), + defaultValue: project.name, + }, + }); + }; + + const onClick = () => { + setSelectedProject(project); + setIsEditorDrawerOpened(false); + }; + + return ( + + + {project.name} + + + + ); +}; + +export default ProjectMobile; diff --git a/src/app/deals/drawers/ProjectsEditorDrawer/index.ts b/src/app/deals/drawers/ProjectsEditorDrawer/index.ts new file mode 100644 index 0000000..906564b --- /dev/null +++ b/src/app/deals/drawers/ProjectsEditorDrawer/index.ts @@ -0,0 +1,3 @@ +import ProjectsEditorDrawer from "@/app/deals/drawers/ProjectsEditorDrawer/ProjectsEditorDrawer"; + +export default ProjectsEditorDrawer; diff --git a/src/app/deals/page.tsx b/src/app/deals/page.tsx index b71e48f..f1c4db9 100644 --- a/src/app/deals/page.tsx +++ b/src/app/deals/page.tsx @@ -5,6 +5,7 @@ import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext"; import { StatusesContextProvider } from "@/app/deals/contexts/StatusesContext"; import BoardStatusesEditorDrawer from "@/app/deals/drawers/BoardStatusesEditorDrawer"; import ProjectBoardsEditorDrawer from "@/app/deals/drawers/ProjectBoardsEditorDrawer"; +import ProjectsEditorDrawer from "@/app/deals/drawers/ProjectsEditorDrawer"; import PageBlock from "@/components/layout/PageBlock/PageBlock"; import PageContainer from "@/components/layout/PageContainer/PageContainer"; import { DealsContextProvider } from "./contexts/DealsContext"; @@ -27,6 +28,7 @@ export default function DealsPage() { + diff --git a/src/hooks/useProjectsList.ts b/src/hooks/useProjectsList.ts index 0053dfa..7d3816f 100644 --- a/src/hooks/useProjectsList.ts +++ b/src/hooks/useProjectsList.ts @@ -1,12 +1,22 @@ +import { useEffect, useState } from "react"; import { useQuery } from "@tanstack/react-query"; +import { ProjectSchema } from "@/lib/client"; import { getProjectsOptions } from "@/lib/client/@tanstack/react-query.gen"; const useProjectsList = () => { + const [projects, setProjects] = useState([]); + const { data, refetch, isLoading } = useQuery({ ...getProjectsOptions(), }); - const projects = !data ? [] : data.projects; - return { projects, refetch, isLoading }; + + useEffect(() => { + if (data?.projects) { + setProjects(data.projects); + } + }, [data?.projects]); + + return { projects, setProjects, refetch, isLoading }; }; export default useProjectsList; diff --git a/src/hooks/useProjectsOperations.tsx b/src/hooks/useProjectsOperations.tsx new file mode 100644 index 0000000..9d46498 --- /dev/null +++ b/src/hooks/useProjectsOperations.tsx @@ -0,0 +1,112 @@ +import React from "react"; +import { useMutation } from "@tanstack/react-query"; +import { AxiosError } from "axios"; +import { Text } from "@mantine/core"; +import { modals } from "@mantine/modals"; +import { + HttpValidationError, + ProjectSchema, + UpdateProjectSchema, +} from "@/lib/client"; +import { + createProjectMutation, + deleteProjectMutation, + updateProjectMutation, +} from "@/lib/client/@tanstack/react-query.gen"; +import { notifications } from "@/lib/notifications"; + +type Props = { + projects: ProjectSchema[]; + setProjects: React.Dispatch>; + refetchProjects: () => void; +}; + +export const useProjectsOperations = ({ + projects, + setProjects, + refetchProjects, +}: Props) => { + const onError = (error: AxiosError) => { + console.error(error); + notifications.error({ + message: error.response?.data?.detail as string | undefined, + }); + refetchProjects(); + }; + + const createProject = useMutation({ + ...createProjectMutation(), + onError, + onSuccess: res => { + setProjects([...projects, res.project]); + }, + }); + + const updateProject = useMutation({ + ...updateProjectMutation(), + onError, + }); + + const deleteProject = useMutation({ + ...deleteProjectMutation(), + onError, + }); + + const onCreateProject = (name: string) => { + createProject.mutate({ + body: { + project: { + name, + }, + }, + }); + }; + + const onUpdateProject = ( + projectId: number, + project: UpdateProjectSchema + ) => { + updateProject.mutate({ + query: { projectId }, + body: { project }, + }); + + setProjects(boards => + boards.map(oldProject => + oldProject.id !== projectId + ? oldProject + : { + id: oldProject.id, + name: project.name ? project.name : oldProject.name, + } + ) + ); + }; + + const onDeleteProject = (project: ProjectSchema) => { + modals.openConfirmModal({ + title: "Удаление проекта", + children: ( + + Вы уверены, что хотите удалить проект "{project.name}"? + + ), + labels: { confirm: "Да", cancel: "Нет" }, + confirmProps: { color: "red" }, + onConfirm: () => { + deleteProject.mutate({ + query: { projectId: project.id }, + }); + setProjects(projects => + projects.filter(p => p.id !== project.id) + ); + }, + }); + }; + + return { + onCreateProject, + onUpdateProject, + onDeleteProject, + }; +}; diff --git a/src/lib/client/@tanstack/react-query.gen.ts b/src/lib/client/@tanstack/react-query.gen.ts index 3ef51ed..53f95f4 100644 --- a/src/lib/client/@tanstack/react-query.gen.ts +++ b/src/lib/client/@tanstack/react-query.gen.ts @@ -1,22 +1,80 @@ // This file is auto-generated by @hey-api/openapi-ts -import { type Options, getBoards, createBoard, deleteBoard, updateBoard, getDeals, updateDeal, getProjects, getStatuses, createStatus, deleteStatus, updateStatus } from '../sdk.gen'; -import { queryOptions, type UseMutationOptions } from '@tanstack/react-query'; -import type { GetBoardsData, CreateBoardData, CreateBoardError, CreateBoardResponse2, DeleteBoardData, DeleteBoardError, DeleteBoardResponse2, UpdateBoardData, UpdateBoardError, UpdateBoardResponse2, GetDealsData, UpdateDealData, UpdateDealError, UpdateDealResponse2, GetProjectsData, GetStatusesData, CreateStatusData, CreateStatusError, CreateStatusResponse2, DeleteStatusData, DeleteStatusError, DeleteStatusResponse2, UpdateStatusData, UpdateStatusError, UpdateStatusResponse2 } from '../types.gen'; -import type { AxiosError } from 'axios'; -import { client as _heyApiClient } from '../client.gen'; +import { queryOptions, type UseMutationOptions } from "@tanstack/react-query"; +import type { AxiosError } from "axios"; +import { client as _heyApiClient } from "../client.gen"; +import { + createBoard, + createProject, + createStatus, + deleteBoard, + deleteProject, + deleteStatus, + getBoards, + getDeals, + getProjects, + getStatuses, + updateBoard, + updateDeal, + updateProject, + updateStatus, + type Options, +} from "../sdk.gen"; +import type { + CreateBoardData, + CreateBoardError, + CreateBoardResponse2, + CreateProjectData, + CreateProjectError, + CreateProjectResponse2, + CreateStatusData, + CreateStatusError, + CreateStatusResponse2, + DeleteBoardData, + DeleteBoardError, + DeleteBoardResponse2, + DeleteProjectData, + DeleteProjectError, + DeleteProjectResponse2, + DeleteStatusData, + DeleteStatusError, + DeleteStatusResponse2, + GetBoardsData, + GetDealsData, + GetProjectsData, + GetStatusesData, + UpdateBoardData, + UpdateBoardError, + UpdateBoardResponse2, + UpdateDealData, + UpdateDealError, + UpdateDealResponse2, + UpdateProjectData, + UpdateProjectError, + UpdateProjectResponse2, + UpdateStatusData, + UpdateStatusError, + UpdateStatusResponse2, +} from "../types.gen"; export type QueryKey = [ - Pick & { + Pick & { _id: string; _infinite?: boolean; - } + }, ]; -const createQueryKey = (id: string, options?: TOptions, infinite?: boolean): [ - QueryKey[0] -] => { - const params: QueryKey[0] = { _id: id, baseURL: options?.baseURL || (options?.client ?? _heyApiClient).getConfig().baseURL } as QueryKey[0]; +const createQueryKey = ( + id: string, + options?: TOptions, + infinite?: boolean +): [QueryKey[0]] => { + const params: QueryKey[0] = { + _id: id, + baseURL: + options?.baseURL || + (options?.client ?? _heyApiClient).getConfig().baseURL, + } as QueryKey[0]; if (infinite) { params._infinite = infinite; } @@ -32,12 +90,11 @@ const createQueryKey = (id: string, options?: TOptions if (options?.query) { params.query = options.query; } - return [ - params - ]; + return [params]; }; -export const getBoardsQueryKey = (options: Options) => createQueryKey('getBoards', options); +export const getBoardsQueryKey = (options: Options) => + createQueryKey("getBoards", options); /** * Get Boards @@ -49,15 +106,16 @@ export const getBoardsOptions = (options: Options) => { ...options, ...queryKey[0], signal, - throwOnError: true + throwOnError: true, }); return data; }, - queryKey: getBoardsQueryKey(options) + queryKey: getBoardsQueryKey(options), }); }; -export const createBoardQueryKey = (options: Options) => createQueryKey('createBoard', options); +export const createBoardQueryKey = (options: Options) => + createQueryKey("createBoard", options); /** * Create Board @@ -69,27 +127,37 @@ export const createBoardOptions = (options: Options) => { ...options, ...queryKey[0], signal, - throwOnError: true + throwOnError: true, }); return data; }, - queryKey: createBoardQueryKey(options) + queryKey: createBoardQueryKey(options), }); }; /** * Create Board */ -export const createBoardMutation = (options?: Partial>): UseMutationOptions, Options> => { - const mutationOptions: UseMutationOptions, Options> = { - mutationFn: async (localOptions) => { +export const createBoardMutation = ( + options?: Partial> +): UseMutationOptions< + CreateBoardResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + CreateBoardResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { const { data } = await createBoard({ ...options, ...localOptions, - throwOnError: true + throwOnError: true, }); return data; - } + }, }; return mutationOptions; }; @@ -97,16 +165,26 @@ export const createBoardMutation = (options?: Partial>) /** * Delete Board */ -export const deleteBoardMutation = (options?: Partial>): UseMutationOptions, Options> => { - const mutationOptions: UseMutationOptions, Options> = { - mutationFn: async (localOptions) => { +export const deleteBoardMutation = ( + options?: Partial> +): UseMutationOptions< + DeleteBoardResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + DeleteBoardResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { const { data } = await deleteBoard({ ...options, ...localOptions, - throwOnError: true + throwOnError: true, }); return data; - } + }, }; return mutationOptions; }; @@ -114,21 +192,32 @@ export const deleteBoardMutation = (options?: Partial>) /** * Update Board */ -export const updateBoardMutation = (options?: Partial>): UseMutationOptions, Options> => { - const mutationOptions: UseMutationOptions, Options> = { - mutationFn: async (localOptions) => { +export const updateBoardMutation = ( + options?: Partial> +): UseMutationOptions< + UpdateBoardResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + UpdateBoardResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { const { data } = await updateBoard({ ...options, ...localOptions, - throwOnError: true + throwOnError: true, }); return data; - } + }, }; return mutationOptions; }; -export const getDealsQueryKey = (options: Options) => createQueryKey('getDeals', options); +export const getDealsQueryKey = (options: Options) => + createQueryKey("getDeals", options); /** * Get Deals @@ -140,32 +229,43 @@ export const getDealsOptions = (options: Options) => { ...options, ...queryKey[0], signal, - throwOnError: true + throwOnError: true, }); return data; }, - queryKey: getDealsQueryKey(options) + queryKey: getDealsQueryKey(options), }); }; /** * Update Deal */ -export const updateDealMutation = (options?: Partial>): UseMutationOptions, Options> => { - const mutationOptions: UseMutationOptions, Options> = { - mutationFn: async (localOptions) => { +export const updateDealMutation = ( + options?: Partial> +): UseMutationOptions< + UpdateDealResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + UpdateDealResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { const { data } = await updateDeal({ ...options, ...localOptions, - throwOnError: true + throwOnError: true, }); return data; - } + }, }; return mutationOptions; }; -export const getProjectsQueryKey = (options?: Options) => createQueryKey('getProjects', options); +export const getProjectsQueryKey = (options?: Options) => + createQueryKey("getProjects", options); /** * Get Projects @@ -177,15 +277,118 @@ export const getProjectsOptions = (options?: Options) => { ...options, ...queryKey[0], signal, - throwOnError: true + throwOnError: true, }); return data; }, - queryKey: getProjectsQueryKey(options) + queryKey: getProjectsQueryKey(options), }); }; -export const getStatusesQueryKey = (options: Options) => createQueryKey('getStatuses', options); +export const createProjectQueryKey = (options: Options) => + createQueryKey("createProject", options); + +/** + * Create Project + */ +export const createProjectOptions = (options: Options) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await createProject({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: createProjectQueryKey(options), + }); +}; + +/** + * Create Project + */ +export const createProjectMutation = ( + options?: Partial> +): UseMutationOptions< + CreateProjectResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + CreateProjectResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { + const { data } = await createProject({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + +/** + * Delete Project + */ +export const deleteProjectMutation = ( + options?: Partial> +): UseMutationOptions< + DeleteProjectResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + DeleteProjectResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { + const { data } = await deleteProject({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + +/** + * Update Project + */ +export const updateProjectMutation = ( + options?: Partial> +): UseMutationOptions< + UpdateProjectResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + UpdateProjectResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { + const { data } = await updateProject({ + ...options, + ...localOptions, + throwOnError: true, + }); + return data; + }, + }; + return mutationOptions; +}; + +export const getStatusesQueryKey = (options: Options) => + createQueryKey("getStatuses", options); /** * Get Statuses @@ -197,15 +400,16 @@ export const getStatusesOptions = (options: Options) => { ...options, ...queryKey[0], signal, - throwOnError: true + throwOnError: true, }); return data; }, - queryKey: getStatusesQueryKey(options) + queryKey: getStatusesQueryKey(options), }); }; -export const createStatusQueryKey = (options: Options) => createQueryKey('createStatus', options); +export const createStatusQueryKey = (options: Options) => + createQueryKey("createStatus", options); /** * Create Status @@ -217,27 +421,37 @@ export const createStatusOptions = (options: Options) => { ...options, ...queryKey[0], signal, - throwOnError: true + throwOnError: true, }); return data; }, - queryKey: createStatusQueryKey(options) + queryKey: createStatusQueryKey(options), }); }; /** * Create Status */ -export const createStatusMutation = (options?: Partial>): UseMutationOptions, Options> => { - const mutationOptions: UseMutationOptions, Options> = { - mutationFn: async (localOptions) => { +export const createStatusMutation = ( + options?: Partial> +): UseMutationOptions< + CreateStatusResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + CreateStatusResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { const { data } = await createStatus({ ...options, ...localOptions, - throwOnError: true + throwOnError: true, }); return data; - } + }, }; return mutationOptions; }; @@ -245,16 +459,26 @@ export const createStatusMutation = (options?: Partial /** * Delete Status */ -export const deleteStatusMutation = (options?: Partial>): UseMutationOptions, Options> => { - const mutationOptions: UseMutationOptions, Options> = { - mutationFn: async (localOptions) => { +export const deleteStatusMutation = ( + options?: Partial> +): UseMutationOptions< + DeleteStatusResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + DeleteStatusResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { const { data } = await deleteStatus({ ...options, ...localOptions, - throwOnError: true + throwOnError: true, }); return data; - } + }, }; return mutationOptions; }; @@ -262,16 +486,26 @@ export const deleteStatusMutation = (options?: Partial /** * Update Status */ -export const updateStatusMutation = (options?: Partial>): UseMutationOptions, Options> => { - const mutationOptions: UseMutationOptions, Options> = { - mutationFn: async (localOptions) => { +export const updateStatusMutation = ( + options?: Partial> +): UseMutationOptions< + UpdateStatusResponse2, + AxiosError, + Options +> => { + const mutationOptions: UseMutationOptions< + UpdateStatusResponse2, + AxiosError, + Options + > = { + mutationFn: async localOptions => { const { data } = await updateStatus({ ...options, ...localOptions, - throwOnError: true + throwOnError: true, }); return data; - } + }, }; return mutationOptions; -}; \ No newline at end of file +}; diff --git a/src/lib/client/client.gen.ts b/src/lib/client/client.gen.ts index 120694c..361e7fc 100644 --- a/src/lib/client/client.gen.ts +++ b/src/lib/client/client.gen.ts @@ -1,8 +1,13 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { ClientOptions } from './types.gen'; -import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from './client'; -import { createClientConfig } from '../../hey-api-config'; +import { createClientConfig } from "../../hey-api-config"; +import { + createClient, + createConfig, + type Config, + type ClientOptions as DefaultClientOptions, +} from "./client"; +import type { ClientOptions } from "./types.gen"; /** * The `createClientConfig()` function will be called on client initialization @@ -12,8 +17,15 @@ import { createClientConfig } from '../../hey-api-config'; * `setConfig()`. This is useful for example if you're using Next.js * to ensure your client always has the correct values. */ -export type CreateClientConfig = (override?: Config) => Config & T>; +export type CreateClientConfig = + ( + override?: Config + ) => Config & T>; -export const client = createClient(createClientConfig(createConfig({ - baseURL: '/api' -}))); \ No newline at end of file +export const client = createClient( + createClientConfig( + createConfig({ + baseURL: "/api", + }) + ) +); diff --git a/src/lib/client/client/client.ts b/src/lib/client/client/client.ts index 41b7494..e94e50a 100644 --- a/src/lib/client/client/client.ts +++ b/src/lib/client/client/client.ts @@ -1,115 +1,114 @@ -import type { AxiosError, RawAxiosRequestHeaders } from 'axios'; -import axios from 'axios'; - -import type { Client, Config } from './types'; +import type { AxiosError, RawAxiosRequestHeaders } from "axios"; +import axios from "axios"; +import type { Client, Config } from "./types"; import { - buildUrl, - createConfig, - mergeConfigs, - mergeHeaders, - setAuthParams, -} from './utils'; + buildUrl, + createConfig, + mergeConfigs, + mergeHeaders, + setAuthParams, +} from "./utils"; export const createClient = (config: Config = {}): Client => { - let _config = mergeConfigs(createConfig(), config); + let _config = mergeConfigs(createConfig(), config); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { auth, ...configWithoutAuth } = _config; - const instance = axios.create(configWithoutAuth); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { auth, ...configWithoutAuth } = _config; + const instance = axios.create(configWithoutAuth); - const getConfig = (): Config => ({ ..._config }); + const getConfig = (): Config => ({ ..._config }); - const setConfig = (config: Config): Config => { - _config = mergeConfigs(_config, config); - instance.defaults = { - ...instance.defaults, - ..._config, - // @ts-expect-error - headers: mergeHeaders(instance.defaults.headers, _config.headers), - }; - return getConfig(); - }; - - // @ts-expect-error - const request: Client['request'] = async (options) => { - const opts = { - ..._config, - ...options, - axios: options.axios ?? _config.axios ?? instance, - headers: mergeHeaders(_config.headers, options.headers), + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + instance.defaults = { + ...instance.defaults, + ..._config, + // @ts-expect-error + headers: mergeHeaders(instance.defaults.headers, _config.headers), + }; + return getConfig(); }; - if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security, - }); - } + // @ts-expect-error + const request: Client["request"] = async options => { + const opts = { + ..._config, + ...options, + axios: options.axios ?? _config.axios ?? instance, + headers: mergeHeaders(_config.headers, options.headers), + }; - if (opts.requestValidator) { - await opts.requestValidator(opts); - } - - if (opts.body && opts.bodySerializer) { - opts.body = opts.bodySerializer(opts.body); - } - - const url = buildUrl(opts); - - try { - // assign Axios here for consistency with fetch - const _axios = opts.axios!; - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { auth, ...optsWithoutAuth } = opts; - const response = await _axios({ - ...optsWithoutAuth, - baseURL: opts.baseURL as string, - data: opts.body, - headers: opts.headers as RawAxiosRequestHeaders, - // let `paramsSerializer()` handle query params if it exists - params: opts.paramsSerializer ? opts.query : undefined, - url, - }); - - let { data } = response; - - if (opts.responseType === 'json') { - if (opts.responseValidator) { - await opts.responseValidator(data); + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); } - if (opts.responseTransformer) { - data = await opts.responseTransformer(data); + if (opts.requestValidator) { + await opts.requestValidator(opts); } - } - return { - ...response, - data: data ?? {}, - }; - } catch (error) { - const e = error as AxiosError; - if (opts.throwOnError) { - throw e; - } - // @ts-expect-error - e.error = e.response?.data ?? {}; - return e; - } - }; + if (opts.body && opts.bodySerializer) { + opts.body = opts.bodySerializer(opts.body); + } - return { - buildUrl, - delete: (options) => request({ ...options, method: 'DELETE' }), - get: (options) => request({ ...options, method: 'GET' }), - getConfig, - head: (options) => request({ ...options, method: 'HEAD' }), - instance, - options: (options) => request({ ...options, method: 'OPTIONS' }), - patch: (options) => request({ ...options, method: 'PATCH' }), - post: (options) => request({ ...options, method: 'POST' }), - put: (options) => request({ ...options, method: 'PUT' }), - request, - setConfig, - } as Client; + const url = buildUrl(opts); + + try { + // assign Axios here for consistency with fetch + const _axios = opts.axios!; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { auth, ...optsWithoutAuth } = opts; + const response = await _axios({ + ...optsWithoutAuth, + baseURL: opts.baseURL as string, + data: opts.body, + headers: opts.headers as RawAxiosRequestHeaders, + // let `paramsSerializer()` handle query params if it exists + params: opts.paramsSerializer ? opts.query : undefined, + url, + }); + + let { data } = response; + + if (opts.responseType === "json") { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return { + ...response, + data: data ?? {}, + }; + } catch (error) { + const e = error as AxiosError; + if (opts.throwOnError) { + throw e; + } + // @ts-expect-error + e.error = e.response?.data ?? {}; + return e; + } + }; + + return { + buildUrl, + delete: options => request({ ...options, method: "DELETE" }), + get: options => request({ ...options, method: "GET" }), + getConfig, + head: options => request({ ...options, method: "HEAD" }), + instance, + options: options => request({ ...options, method: "OPTIONS" }), + patch: options => request({ ...options, method: "PATCH" }), + post: options => request({ ...options, method: "POST" }), + put: options => request({ ...options, method: "PUT" }), + request, + setConfig, + } as Client; }; diff --git a/src/lib/client/client/index.ts b/src/lib/client/client/index.ts index 15d3742..b73b654 100644 --- a/src/lib/client/client/index.ts +++ b/src/lib/client/client/index.ts @@ -1,21 +1,21 @@ -export type { Auth } from '../core/auth'; -export type { QuerySerializerOptions } from '../core/bodySerializer'; +export type { Auth } from "../core/auth"; +export type { QuerySerializerOptions } from "../core/bodySerializer"; export { - formDataBodySerializer, - jsonBodySerializer, - urlSearchParamsBodySerializer, -} from '../core/bodySerializer'; -export { buildClientParams } from '../core/params'; -export { createClient } from './client'; + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from "../core/bodySerializer"; +export { buildClientParams } from "../core/params"; +export { createClient } from "./client"; export type { - Client, - ClientOptions, - Config, - CreateClientConfig, - Options, - OptionsLegacyParser, - RequestOptions, - RequestResult, - TDataShape, -} from './types'; -export { createConfig } from './utils'; + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + OptionsLegacyParser, + RequestOptions, + RequestResult, + TDataShape, +} from "./types"; +export { createConfig } from "./utils"; diff --git a/src/lib/client/client/types.ts b/src/lib/client/client/types.ts index 2186628..4d72bd6 100644 --- a/src/lib/client/client/types.ts +++ b/src/lib/client/client/types.ts @@ -1,138 +1,141 @@ import type { - AxiosError, - AxiosInstance, - AxiosRequestHeaders, - AxiosResponse, - AxiosStatic, - CreateAxiosDefaults, -} from 'axios'; - -import type { Auth } from '../core/auth'; -import type { - Client as CoreClient, - Config as CoreConfig, -} from '../core/types'; + AxiosError, + AxiosInstance, + AxiosRequestHeaders, + AxiosResponse, + AxiosStatic, + CreateAxiosDefaults, +} from "axios"; +import type { Auth } from "../core/auth"; +import type { Client as CoreClient, Config as CoreConfig } from "../core/types"; export interface Config - extends Omit, - CoreConfig { - /** - * Axios implementation. You can use this option to provide a custom - * Axios instance. - * - * @default axios - */ - axios?: AxiosStatic; - /** - * Base URL for all requests made by this client. - */ - baseURL?: T['baseURL']; - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | AxiosRequestHeaders - | Record< - string, - | string - | number - | boolean - | (string | number | boolean)[] - | null - | undefined - | unknown - >; - /** - * Throw an error instead of returning it in the response? - * - * @default false - */ - throwOnError?: T['throwOnError']; + extends Omit< + CreateAxiosDefaults, + "auth" | "baseURL" | "headers" | "method" + >, + CoreConfig { + /** + * Axios implementation. You can use this option to provide a custom + * Axios instance. + * + * @default axios + */ + axios?: AxiosStatic; + /** + * Base URL for all requests made by this client. + */ + baseURL?: T["baseURL"]; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | AxiosRequestHeaders + | Record< + string, + | string + | number + | boolean + | (string | number | boolean)[] + | null + | undefined + | unknown + >; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T["throwOnError"]; } export interface RequestOptions< - ThrowOnError extends boolean = boolean, - Url extends string = string, + ThrowOnError extends boolean = boolean, + Url extends string = string, > extends Config<{ - throwOnError: ThrowOnError; - }> { - /** - * Any body that you want to add to your request. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} - */ - body?: unknown; - path?: Record; - query?: Record; - /** - * Security mechanism(s) to use for the request. - */ - security?: ReadonlyArray; - url: Url; -} - -export type RequestResult< - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = boolean, -> = ThrowOnError extends true - ? Promise< - AxiosResponse< - TData extends Record ? TData[keyof TData] : TData - > - > - : Promise< - | (AxiosResponse< - TData extends Record ? TData[keyof TData] : TData - > & { error: undefined }) - | (AxiosError< - TError extends Record ? TError[keyof TError] : TError - > & { - data: undefined; - error: TError extends Record - ? TError[keyof TError] - : TError; - }) - >; - -export interface ClientOptions { - baseURL?: string; - throwOnError?: boolean; -} - -type MethodFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, ->( - options: Omit, 'method'>, -) => RequestResult; - -type RequestFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, ->( - options: Omit, 'method'> & - Pick>, 'method'>, -) => RequestResult; - -type BuildUrlFn = < - TData extends { + throwOnError: ThrowOnError; + }> { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ body?: unknown; path?: Record; query?: Record; - url: string; - }, + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, +> = ThrowOnError extends true + ? Promise< + AxiosResponse< + TData extends Record ? TData[keyof TData] : TData + > + > + : Promise< + | (AxiosResponse< + TData extends Record + ? TData[keyof TData] + : TData + > & { error: undefined }) + | (AxiosError< + TError extends Record + ? TError[keyof TError] + : TError + > & { + data: undefined; + error: TError extends Record + ? TError[keyof TError] + : TError; + }) + >; + +export interface ClientOptions { + baseURL?: string; + throwOnError?: boolean; +} + +type MethodFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, >( - options: Pick & Omit, 'axios'>, + options: Omit, "method"> +) => RequestResult; + +type RequestFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, +>( + options: Omit, "method"> & + Pick>, "method"> +) => RequestResult; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + }, +>( + options: Pick & Omit, "axios"> ) => string; export type Client = CoreClient & { - instance: AxiosInstance; + instance: AxiosInstance; }; /** @@ -144,36 +147,37 @@ export type Client = CoreClient & { * to ensure your client always has the correct values. */ export type CreateClientConfig = ( - override?: Config, + override?: Config ) => Config & T>; export interface TDataShape { - body?: unknown; - headers?: unknown; - path?: unknown; - query?: unknown; - url: string; + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; } type OmitKeys = Pick>; export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean, -> = OmitKeys, 'body' | 'path' | 'query' | 'url'> & - Omit; + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, +> = OmitKeys, "body" | "path" | "query" | "url"> & + Omit; export type OptionsLegacyParser< - TData = unknown, - ThrowOnError extends boolean = boolean, + TData = unknown, + ThrowOnError extends boolean = boolean, > = TData extends { body?: any } - ? TData extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & TData - : OmitKeys, 'body' | 'url'> & - TData & - Pick, 'headers'> - : TData extends { headers?: any } - ? OmitKeys, 'headers' | 'url'> & - TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData; + ? TData extends { headers?: any } + ? OmitKeys, "body" | "headers" | "url"> & + TData + : OmitKeys, "body" | "url"> & + TData & + Pick, "headers"> + : TData extends { headers?: any } + ? OmitKeys, "headers" | "url"> & + TData & + Pick, "body"> + : OmitKeys, "url"> & TData; diff --git a/src/lib/client/client/utils.ts b/src/lib/client/client/utils.ts index f0eab72..8d86d8a 100644 --- a/src/lib/client/client/utils.ts +++ b/src/lib/client/client/utils.ts @@ -1,286 +1,292 @@ -import { getAuthToken } from '../core/auth'; +import { getAuthToken } from "../core/auth"; import type { - QuerySerializer, - QuerySerializerOptions, -} from '../core/bodySerializer'; -import type { ArraySeparatorStyle } from '../core/pathSerializer'; + QuerySerializer, + QuerySerializerOptions, +} from "../core/bodySerializer"; +import type { ArraySeparatorStyle } from "../core/pathSerializer"; import { - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam, -} from '../core/pathSerializer'; -import type { Client, ClientOptions, Config, RequestOptions } from './types'; + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from "../core/pathSerializer"; +import type { Client, ClientOptions, Config, RequestOptions } from "./types"; interface PathSerializer { - path: Record; - url: string; + path: Record; + url: string; } const PATH_PARAM_RE = /\{[^{}]+\}/g; const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url; - const matches = _url.match(PATH_PARAM_RE); - if (matches) { - for (const match of matches) { - let explode = false; - let name = match.substring(1, match.length - 1); - let style: ArraySeparatorStyle = 'simple'; + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = "simple"; - if (name.endsWith('*')) { - explode = true; - name = name.substring(0, name.length - 1); - } + if (name.endsWith("*")) { + explode = true; + name = name.substring(0, name.length - 1); + } - if (name.startsWith('.')) { - name = name.substring(1); - style = 'label'; - } else if (name.startsWith(';')) { - name = name.substring(1); - style = 'matrix'; - } + if (name.startsWith(".")) { + name = name.substring(1); + style = "label"; + } else if (name.startsWith(";")) { + name = name.substring(1); + style = "matrix"; + } - const value = path[name]; + const value = path[name]; - if (value === undefined || value === null) { - continue; - } + if (value === undefined || value === null) { + continue; + } - if (Array.isArray(value)) { - url = url.replace( - match, - serializeArrayParam({ explode, name, style, value }), - ); - continue; - } + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }) + ); + continue; + } - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true, - }), - ); - continue; - } + if (typeof value === "object") { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }) + ); + continue; + } - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string, - })}`, - ); - continue; - } + if (style === "matrix") { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}` + ); + continue; + } - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string), - ); - url = url.replace(match, replaceValue); + const replaceValue = encodeURIComponent( + style === "label" ? `.${value as string}` : (value as string) + ); + url = url.replace(match, replaceValue); + } } - } - return url; + return url; }; export const createQuerySerializer = ({ - allowReserved, - array, - object, + allowReserved, + array, + object, }: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { - const search: string[] = []; - if (queryParams && typeof queryParams === 'object') { - for (const name in queryParams) { - const value = queryParams[name]; + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === "object") { + for (const name in queryParams) { + const value = queryParams[name]; - if (value === undefined || value === null) { - continue; - } + if (value === undefined || value === null) { + continue; + } - if (Array.isArray(value)) { - const serializedArray = serializeArrayParam({ - allowReserved, - explode: true, - name, - style: 'form', - value, - ...array, - }); - if (serializedArray) search.push(serializedArray); - } else if (typeof value === 'object') { - const serializedObject = serializeObjectParam({ - allowReserved, - explode: true, - name, - style: 'deepObject', - value: value as Record, - ...object, - }); - if (serializedObject) search.push(serializedObject); - } else { - const serializedPrimitive = serializePrimitiveParam({ - allowReserved, - name, - value: value as string, - }); - if (serializedPrimitive) search.push(serializedPrimitive); + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved, + explode: true, + name, + style: "form", + value, + ...array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === "object") { + const serializedObject = serializeObjectParam({ + allowReserved, + explode: true, + name, + style: "deepObject", + value: value as Record, + ...object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } } - } - } - return search.join('&'); - }; - return querySerializer; + return search.join("&"); + }; + return querySerializer; }; export const setAuthParams = async ({ - security, - ...options -}: Pick, 'security'> & - Pick & { - headers: Record; - }) => { - for (const auth of security) { - const token = await getAuthToken(auth, options.auth); + security, + ...options +}: Pick, "security"> & + Pick & { + headers: Record; + }) => { + for (const auth of security) { + const token = await getAuthToken(auth, options.auth); - if (!token) { - continue; - } - - const name = auth.name ?? 'Authorization'; - - switch (auth.in) { - case 'query': - if (!options.query) { - options.query = {}; + if (!token) { + continue; } - options.query[name] = token; - break; - case 'cookie': { - const value = `${name}=${token}`; - if ('Cookie' in options.headers && options.headers['Cookie']) { - options.headers['Cookie'] = `${options.headers['Cookie']}; ${value}`; - } else { - options.headers['Cookie'] = value; - } - break; - } - case 'header': - default: - options.headers[name] = token; - break; - } - return; - } + const name = auth.name ?? "Authorization"; + + switch (auth.in) { + case "query": + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case "cookie": { + const value = `${name}=${token}`; + if ("Cookie" in options.headers && options.headers["Cookie"]) { + options.headers["Cookie"] = + `${options.headers["Cookie"]}; ${value}`; + } else { + options.headers["Cookie"] = value; + } + break; + } + case "header": + default: + options.headers[name] = token; + break; + } + + return; + } }; -export const buildUrl: Client['buildUrl'] = (options) => { - const url = getUrl({ - path: options.path, - // let `paramsSerializer()` handle query params if it exists - query: !options.paramsSerializer ? options.query : undefined, - querySerializer: - typeof options.querySerializer === 'function' - ? options.querySerializer - : createQuerySerializer(options.querySerializer), - url: options.url, - }); - return url; +export const buildUrl: Client["buildUrl"] = options => { + const url = getUrl({ + path: options.path, + // let `paramsSerializer()` handle query params if it exists + query: !options.paramsSerializer ? options.query : undefined, + querySerializer: + typeof options.querySerializer === "function" + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); + return url; }; export const getUrl = ({ - path, - query, - querySerializer, - url: _url, + path, + query, + querySerializer, + url: _url, }: { - path?: Record; - query?: Record; - querySerializer: QuerySerializer; - url: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; }) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; - let url = pathUrl; - if (path) { - url = defaultPathSerializer({ path, url }); - } - let search = query ? querySerializer(query) : ''; - if (search.startsWith('?')) { - search = search.substring(1); - } - if (search) { - url += `?${search}`; - } - return url; + const pathUrl = _url.startsWith("/") ? _url : `/${_url}`; + let url = pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ""; + if (search.startsWith("?")) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; }; export const mergeConfigs = (a: Config, b: Config): Config => { - const config = { ...a, ...b }; - config.headers = mergeHeaders(a.headers, b.headers); - return config; + const config = { ...a, ...b }; + config.headers = mergeHeaders(a.headers, b.headers); + return config; }; /** * Special Axios headers keywords allowing to set headers by request method. */ export const axiosHeadersKeywords = [ - 'common', - 'delete', - 'get', - 'head', - 'patch', - 'post', - 'put', + "common", + "delete", + "get", + "head", + "patch", + "post", + "put", ] as const; export const mergeHeaders = ( - ...headers: Array['headers'] | undefined> + ...headers: Array["headers"] | undefined> ): Record => { - const mergedHeaders: Record = {}; - for (const header of headers) { - if (!header || typeof header !== 'object') { - continue; - } - - const iterator = Object.entries(header); - - for (const [key, value] of iterator) { - if ( - axiosHeadersKeywords.includes( - key as (typeof axiosHeadersKeywords)[number], - ) && - typeof value === 'object' - ) { - mergedHeaders[key] = { - ...(mergedHeaders[key] as Record), - ...value, - }; - } else if (value === null) { - delete mergedHeaders[key]; - } else if (Array.isArray(value)) { - for (const v of value) { - // @ts-expect-error - mergedHeaders[key] = [...(mergedHeaders[key] ?? []), v as string]; + const mergedHeaders: Record = {}; + for (const header of headers) { + if (!header || typeof header !== "object") { + continue; + } + + const iterator = Object.entries(header); + + for (const [key, value] of iterator) { + if ( + axiosHeadersKeywords.includes( + key as (typeof axiosHeadersKeywords)[number] + ) && + typeof value === "object" + ) { + mergedHeaders[key] = { + ...(mergedHeaders[key] as Record), + ...value, + }; + } else if (value === null) { + delete mergedHeaders[key]; + } else if (Array.isArray(value)) { + for (const v of value) { + // @ts-expect-error + mergedHeaders[key] = [ + ...(mergedHeaders[key] ?? []), + v as string, + ]; + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders[key] = + typeof value === "object" + ? JSON.stringify(value) + : (value as string); + } } - } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their - // content value in OpenAPI specification is 'application/json' - mergedHeaders[key] = - typeof value === 'object' ? JSON.stringify(value) : (value as string); - } } - } - return mergedHeaders; + return mergedHeaders; }; export const createConfig = ( - override: Config & T> = {}, + override: Config & T> = {} ): Config & T> => ({ - ...override, + ...override, }); diff --git a/src/lib/client/core/auth.ts b/src/lib/client/core/auth.ts index 451c7f3..cb59986 100644 --- a/src/lib/client/core/auth.ts +++ b/src/lib/client/core/auth.ts @@ -1,40 +1,40 @@ export type AuthToken = string | undefined; export interface Auth { - /** - * Which part of the request do we use to send the auth? - * - * @default 'header' - */ - in?: 'header' | 'query' | 'cookie'; - /** - * Header or query parameter name. - * - * @default 'Authorization' - */ - name?: string; - scheme?: 'basic' | 'bearer'; - type: 'apiKey' | 'http'; + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: "header" | "query" | "cookie"; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: "basic" | "bearer"; + type: "apiKey" | "http"; } export const getAuthToken = async ( - auth: Auth, - callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken ): Promise => { - const token = - typeof callback === 'function' ? await callback(auth) : callback; + const token = + typeof callback === "function" ? await callback(auth) : callback; - if (!token) { - return; - } + if (!token) { + return; + } - if (auth.scheme === 'bearer') { - return `Bearer ${token}`; - } + if (auth.scheme === "bearer") { + return `Bearer ${token}`; + } - if (auth.scheme === 'basic') { - return `Basic ${btoa(token)}`; - } + if (auth.scheme === "basic") { + return `Basic ${btoa(token)}`; + } - return token; + return token; }; diff --git a/src/lib/client/core/bodySerializer.ts b/src/lib/client/core/bodySerializer.ts index 98ce779..25d311e 100644 --- a/src/lib/client/core/bodySerializer.ts +++ b/src/lib/client/core/bodySerializer.ts @@ -1,88 +1,92 @@ import type { - ArrayStyle, - ObjectStyle, - SerializerOptions, -} from './pathSerializer'; + ArrayStyle, + ObjectStyle, + SerializerOptions, +} from "./pathSerializer"; export type QuerySerializer = (query: Record) => string; export type BodySerializer = (body: any) => any; export interface QuerySerializerOptions { - allowReserved?: boolean; - array?: SerializerOptions; - object?: SerializerOptions; + allowReserved?: boolean; + array?: SerializerOptions; + object?: SerializerOptions; } const serializeFormDataPair = ( - data: FormData, - key: string, - value: unknown, + data: FormData, + key: string, + value: unknown ): void => { - if (typeof value === 'string' || value instanceof Blob) { - data.append(key, value); - } else { - data.append(key, JSON.stringify(value)); - } + if (typeof value === "string" || value instanceof Blob) { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } }; const serializeUrlSearchParamsPair = ( - data: URLSearchParams, - key: string, - value: unknown, + data: URLSearchParams, + key: string, + value: unknown ): void => { - if (typeof value === 'string') { - data.append(key, value); - } else { - data.append(key, JSON.stringify(value)); - } + if (typeof value === "string") { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } }; export const formDataBodySerializer = { - bodySerializer: | Array>>( - body: T, - ): FormData => { - const data = new FormData(); + bodySerializer: < + T extends Record | Array>, + >( + body: T + ): FormData => { + const data = new FormData(); - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return; - } - if (Array.isArray(value)) { - value.forEach((v) => serializeFormDataPair(data, key, v)); - } else { - serializeFormDataPair(data, key, value); - } - }); + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach(v => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); - return data; - }, + return data; + }, }; export const jsonBodySerializer = { - bodySerializer: (body: T): string => - JSON.stringify(body, (_key, value) => - typeof value === 'bigint' ? value.toString() : value, - ), + bodySerializer: (body: T): string => + JSON.stringify(body, (_key, value) => + typeof value === "bigint" ? value.toString() : value + ), }; export const urlSearchParamsBodySerializer = { - bodySerializer: | Array>>( - body: T, - ): string => { - const data = new URLSearchParams(); + bodySerializer: < + T extends Record | Array>, + >( + body: T + ): string => { + const data = new URLSearchParams(); - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return; - } - if (Array.isArray(value)) { - value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); - } else { - serializeUrlSearchParamsPair(data, key, value); - } - }); + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach(v => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); - return data.toString(); - }, + return data.toString(); + }, }; diff --git a/src/lib/client/core/params.ts b/src/lib/client/core/params.ts index ba35263..c407be3 100644 --- a/src/lib/client/core/params.ts +++ b/src/lib/client/core/params.ts @@ -1,151 +1,156 @@ -type Slot = 'body' | 'headers' | 'path' | 'query'; +type Slot = "body" | "headers" | "path" | "query"; export type Field = - | { - in: Exclude; - /** - * Field name. This is the name we want the user to see and use. - */ - key: string; - /** - * Field mapped name. This is the name we want to use in the request. - * If omitted, we use the same value as `key`. - */ - map?: string; - } - | { - in: Extract; - /** - * Key isn't required for bodies. - */ - key?: string; - map?: string; - }; + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + }; export interface Fields { - allowExtra?: Partial>; - args?: ReadonlyArray; + allowExtra?: Partial>; + args?: ReadonlyArray; } export type FieldsConfig = ReadonlyArray; const extraPrefixesMap: Record = { - $body_: 'body', - $headers_: 'headers', - $path_: 'path', - $query_: 'query', + $body_: "body", + $headers_: "headers", + $path_: "path", + $query_: "query", }; const extraPrefixes = Object.entries(extraPrefixesMap); type KeyMap = Map< - string, - { - in: Slot; - map?: string; - } + string, + { + in: Slot; + map?: string; + } >; const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { - if (!map) { - map = new Map(); - } - - for (const config of fields) { - if ('in' in config) { - if (config.key) { - map.set(config.key, { - in: config.in, - map: config.map, - }); - } - } else if (config.args) { - buildKeyMap(config.args, map); + if (!map) { + map = new Map(); } - } - return map; + for (const config of fields) { + if ("in" in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; }; interface Params { - body: unknown; - headers: Record; - path: Record; - query: Record; + body: unknown; + headers: Record; + path: Record; + query: Record; } const stripEmptySlots = (params: Params) => { - for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Object.keys(value).length) { - delete params[slot as Slot]; + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === "object" && !Object.keys(value).length) { + delete params[slot as Slot]; + } } - } }; export const buildClientParams = ( - args: ReadonlyArray, - fields: FieldsConfig, + args: ReadonlyArray, + fields: FieldsConfig ) => { - const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {}, - }; + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; - const map = buildKeyMap(fields); + const map = buildKeyMap(fields); - let config: FieldsConfig[number] | undefined; + let config: FieldsConfig[number] | undefined; - for (const [index, arg] of args.entries()) { - if (fields[index]) { - config = fields[index]; - } - - if (!config) { - continue; - } - - if ('in' in config) { - if (config.key) { - const field = map.get(config.key)!; - const name = field.map || config.key; - (params[field.in] as Record)[name] = arg; - } else { - params.body = arg; - } - } else { - for (const [key, value] of Object.entries(arg ?? {})) { - const field = map.get(key); - - if (field) { - const name = field.map || key; - (params[field.in] as Record)[name] = value; - } else { - const extra = extraPrefixes.find(([prefix]) => - key.startsWith(prefix), - ); - - if (extra) { - const [prefix, slot] = extra; - (params[slot] as Record)[ - key.slice(prefix.length) - ] = value; - } else { - for (const [slot, allowed] of Object.entries( - config.allowExtra ?? {}, - )) { - if (allowed) { - (params[slot as Slot] as Record)[key] = value; - break; - } - } - } + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ("in" in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + (params[field.in] as Record)[name] = arg; + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + const name = field.map || key; + (params[field.in] as Record)[name] = value; + } else { + const extra = extraPrefixes.find(([prefix]) => + key.startsWith(prefix) + ); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[ + key.slice(prefix.length) + ] = value; + } else { + for (const [slot, allowed] of Object.entries( + config.allowExtra ?? {} + )) { + if (allowed) { + ( + params[slot as Slot] as Record< + string, + unknown + > + )[key] = value; + break; + } + } + } + } + } } - } } - } - stripEmptySlots(params); + stripEmptySlots(params); - return params; + return params; }; diff --git a/src/lib/client/core/pathSerializer.ts b/src/lib/client/core/pathSerializer.ts index d692cf0..c66aeff 100644 --- a/src/lib/client/core/pathSerializer.ts +++ b/src/lib/client/core/pathSerializer.ts @@ -1,179 +1,183 @@ interface SerializeOptions - extends SerializePrimitiveOptions, - SerializerOptions {} + extends SerializePrimitiveOptions, + SerializerOptions {} interface SerializePrimitiveOptions { - allowReserved?: boolean; - name: string; + allowReserved?: boolean; + name: string; } export interface SerializerOptions { - /** - * @default true - */ - explode: boolean; - style: T; + /** + * @default true + */ + explode: boolean; + style: T; } -export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArrayStyle = "form" | "spaceDelimited" | "pipeDelimited"; export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; -type MatrixStyle = 'label' | 'matrix' | 'simple'; -export type ObjectStyle = 'form' | 'deepObject'; +type MatrixStyle = "label" | "matrix" | "simple"; +export type ObjectStyle = "form" | "deepObject"; type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; interface SerializePrimitiveParam extends SerializePrimitiveOptions { - value: string; + value: string; } export const separatorArrayExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'label': - return '.'; - case 'matrix': - return ';'; - case 'simple': - return ','; - default: - return '&'; - } + switch (style) { + case "label": + return "."; + case "matrix": + return ";"; + case "simple": + return ","; + default: + return "&"; + } }; export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'form': - return ','; - case 'pipeDelimited': - return '|'; - case 'spaceDelimited': - return '%20'; - default: - return ','; - } + switch (style) { + case "form": + return ","; + case "pipeDelimited": + return "|"; + case "spaceDelimited": + return "%20"; + default: + return ","; + } }; export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { - switch (style) { - case 'label': - return '.'; - case 'matrix': - return ';'; - case 'simple': - return ','; - default: - return '&'; - } + switch (style) { + case "label": + return "."; + case "matrix": + return ";"; + case "simple": + return ","; + default: + return "&"; + } }; export const serializeArrayParam = ({ - allowReserved, - explode, - name, - style, - value, + allowReserved, + explode, + name, + style, + value, }: SerializeOptions & { - value: unknown[]; + value: unknown[]; }) => { - if (!explode) { - const joinedValues = ( - allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) - ).join(separatorArrayNoExplode(style)); - switch (style) { - case 'label': - return `.${joinedValues}`; - case 'matrix': - return `;${name}=${joinedValues}`; - case 'simple': - return joinedValues; - default: - return `${name}=${joinedValues}`; + if (!explode) { + const joinedValues = ( + allowReserved + ? value + : value.map(v => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case "label": + return `.${joinedValues}`; + case "matrix": + return `;${name}=${joinedValues}`; + case "simple": + return joinedValues; + default: + return `${name}=${joinedValues}`; + } } - } - const separator = separatorArrayExplode(style); - const joinedValues = value - .map((v) => { - if (style === 'label' || style === 'simple') { - return allowReserved ? v : encodeURIComponent(v as string); - } + const separator = separatorArrayExplode(style); + const joinedValues = value + .map(v => { + if (style === "label" || style === "simple") { + return allowReserved ? v : encodeURIComponent(v as string); + } - return serializePrimitiveParam({ - allowReserved, - name, - value: v as string, - }); - }) - .join(separator); - return style === 'label' || style === 'matrix' - ? separator + joinedValues - : joinedValues; + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === "label" || style === "matrix" + ? separator + joinedValues + : joinedValues; }; export const serializePrimitiveParam = ({ - allowReserved, - name, - value, + allowReserved, + name, + value, }: SerializePrimitiveParam) => { - if (value === undefined || value === null) { - return ''; - } + if (value === undefined || value === null) { + return ""; + } - if (typeof value === 'object') { - throw new Error( - 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', - ); - } + if (typeof value === "object") { + throw new Error( + "Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these." + ); + } - return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; }; export const serializeObjectParam = ({ - allowReserved, - explode, - name, - style, - value, - valueOnly, + allowReserved, + explode, + name, + style, + value, + valueOnly, }: SerializeOptions & { - value: Record | Date; - valueOnly?: boolean; + value: Record | Date; + valueOnly?: boolean; }) => { - if (value instanceof Date) { - return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; - } - - if (style !== 'deepObject' && !explode) { - let values: string[] = []; - Object.entries(value).forEach(([key, v]) => { - values = [ - ...values, - key, - allowReserved ? (v as string) : encodeURIComponent(v as string), - ]; - }); - const joinedValues = values.join(','); - switch (style) { - case 'form': - return `${name}=${joinedValues}`; - case 'label': - return `.${joinedValues}`; - case 'matrix': - return `;${name}=${joinedValues}`; - default: - return joinedValues; + if (value instanceof Date) { + return valueOnly + ? value.toISOString() + : `${name}=${value.toISOString()}`; } - } - const separator = separatorObjectExplode(style); - const joinedValues = Object.entries(value) - .map(([key, v]) => - serializePrimitiveParam({ - allowReserved, - name: style === 'deepObject' ? `${name}[${key}]` : key, - value: v as string, - }), - ) - .join(separator); - return style === 'label' || style === 'matrix' - ? separator + joinedValues - : joinedValues; + if (style !== "deepObject" && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [ + ...values, + key, + allowReserved ? (v as string) : encodeURIComponent(v as string), + ]; + }); + const joinedValues = values.join(","); + switch (style) { + case "form": + return `${name}=${joinedValues}`; + case "label": + return `.${joinedValues}`; + case "matrix": + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === "deepObject" ? `${name}[${key}]` : key, + value: v as string, + }) + ) + .join(separator); + return style === "label" || style === "matrix" + ? separator + joinedValues + : joinedValues; }; diff --git a/src/lib/client/core/types.ts b/src/lib/client/core/types.ts index 2dd4106..8d2802f 100644 --- a/src/lib/client/core/types.ts +++ b/src/lib/client/core/types.ts @@ -1,118 +1,118 @@ -import type { Auth, AuthToken } from './auth'; +import type { Auth, AuthToken } from "./auth"; import type { - BodySerializer, - QuerySerializer, - QuerySerializerOptions, -} from './bodySerializer'; + BodySerializer, + QuerySerializer, + QuerySerializerOptions, +} from "./bodySerializer"; export interface Client< - RequestFn = never, - Config = unknown, - MethodFn = never, - BuildUrlFn = never, + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, > { - /** - * Returns the final request URL. - */ - buildUrl: BuildUrlFn; - connect: MethodFn; - delete: MethodFn; - get: MethodFn; - getConfig: () => Config; - head: MethodFn; - options: MethodFn; - patch: MethodFn; - post: MethodFn; - put: MethodFn; - request: RequestFn; - setConfig: (config: Config) => Config; - trace: MethodFn; + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + connect: MethodFn; + delete: MethodFn; + get: MethodFn; + getConfig: () => Config; + head: MethodFn; + options: MethodFn; + patch: MethodFn; + post: MethodFn; + put: MethodFn; + request: RequestFn; + setConfig: (config: Config) => Config; + trace: MethodFn; } export interface Config { - /** - * Auth token or a function returning auth token. The resolved value will be - * added to the request payload as defined by its `security` array. - */ - auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; - /** - * A function for serializing request body parameter. By default, - * {@link JSON.stringify()} will be used. - */ - bodySerializer?: BodySerializer | null; - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | RequestInit['headers'] - | Record< - string, - | string - | number - | boolean - | (string | number | boolean)[] - | null - | undefined - | unknown - >; - /** - * The request method. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} - */ - method?: - | 'CONNECT' - | 'DELETE' - | 'GET' - | 'HEAD' - | 'OPTIONS' - | 'PATCH' - | 'POST' - | 'PUT' - | 'TRACE'; - /** - * A function for serializing request query parameters. By default, arrays - * will be exploded in form style, objects will be exploded in deepObject - * style, and reserved characters are percent-encoded. - * - * This method will have no effect if the native `paramsSerializer()` Axios - * API function is used. - * - * {@link https://swagger.io/docs/specification/serialization/#query View examples} - */ - querySerializer?: QuerySerializer | QuerySerializerOptions; - /** - * A function validating request data. This is useful if you want to ensure - * the request conforms to the desired shape, so it can be safely sent to - * the server. - */ - requestValidator?: (data: unknown) => Promise; - /** - * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. - */ - responseTransformer?: (data: unknown) => Promise; - /** - * A function validating response data. This is useful if you want to ensure - * the response conforms to the desired shape, so it can be safely passed to - * the transformers and returned to the user. - */ - responseValidator?: (data: unknown) => Promise; + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit["headers"] + | Record< + string, + | string + | number + | boolean + | (string | number | boolean)[] + | null + | undefined + | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: + | "CONNECT" + | "DELETE" + | "GET" + | "HEAD" + | "OPTIONS" + | "PATCH" + | "POST" + | "PUT" + | "TRACE"; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; } type IsExactlyNeverOrNeverUndefined = [T] extends [never] - ? true - : [T] extends [never | undefined] - ? [undefined] extends [T] - ? false - : true - : false; + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; export type OmitNever> = { - [K in keyof T as IsExactlyNeverOrNeverUndefined extends true - ? never - : K]: T[K]; + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true + ? never + : K]: T[K]; }; diff --git a/src/lib/client/index.ts b/src/lib/client/index.ts index e64537d..da87079 100644 --- a/src/lib/client/index.ts +++ b/src/lib/client/index.ts @@ -1,3 +1,3 @@ // This file is auto-generated by @hey-api/openapi-ts -export * from './types.gen'; -export * from './sdk.gen'; \ No newline at end of file +export * from "./types.gen"; +export * from "./sdk.gen"; diff --git a/src/lib/client/sdk.gen.ts b/src/lib/client/sdk.gen.ts index 8a7f384..ef78780 100644 --- a/src/lib/client/sdk.gen.ts +++ b/src/lib/client/sdk.gen.ts @@ -1,11 +1,85 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { Options as ClientOptions, TDataShape, Client } from './client'; -import type { GetBoardsData, GetBoardsResponses, GetBoardsErrors, CreateBoardData, CreateBoardResponses, CreateBoardErrors, DeleteBoardData, DeleteBoardResponses, DeleteBoardErrors, UpdateBoardData, UpdateBoardResponses, UpdateBoardErrors, GetDealsData, GetDealsResponses, GetDealsErrors, UpdateDealData, UpdateDealResponses, UpdateDealErrors, GetProjectsData, GetProjectsResponses, GetStatusesData, GetStatusesResponses, GetStatusesErrors, CreateStatusData, CreateStatusResponses, CreateStatusErrors, DeleteStatusData, DeleteStatusResponses, DeleteStatusErrors, UpdateStatusData, UpdateStatusResponses, UpdateStatusErrors } from './types.gen'; -import { zGetBoardsData, zGetBoardsResponse2, zCreateBoardData, zCreateBoardResponse2, zDeleteBoardData, zDeleteBoardResponse2, zUpdateBoardData, zUpdateBoardResponse2, zGetDealsData, zGetDealsResponse2, zUpdateDealData, zUpdateDealResponse2, zGetProjectsData, zGetProjectsResponse2, zGetStatusesData, zGetStatusesResponse2, zCreateStatusData, zCreateStatusResponse2, zDeleteStatusData, zDeleteStatusResponse2, zUpdateStatusData, zUpdateStatusResponse2 } from './zod.gen'; -import { client as _heyApiClient } from './client.gen'; +import type { Client, Options as ClientOptions, TDataShape } from "./client"; +import { client as _heyApiClient } from "./client.gen"; +import type { + CreateBoardData, + CreateBoardErrors, + CreateBoardResponses, + CreateProjectData, + CreateProjectErrors, + CreateProjectResponses, + CreateStatusData, + CreateStatusErrors, + CreateStatusResponses, + DeleteBoardData, + DeleteBoardErrors, + DeleteBoardResponses, + DeleteProjectData, + DeleteProjectErrors, + DeleteProjectResponses, + DeleteStatusData, + DeleteStatusErrors, + DeleteStatusResponses, + GetBoardsData, + GetBoardsErrors, + GetBoardsResponses, + GetDealsData, + GetDealsErrors, + GetDealsResponses, + GetProjectsData, + GetProjectsResponses, + GetStatusesData, + GetStatusesErrors, + GetStatusesResponses, + UpdateBoardData, + UpdateBoardErrors, + UpdateBoardResponses, + UpdateDealData, + UpdateDealErrors, + UpdateDealResponses, + UpdateProjectData, + UpdateProjectErrors, + UpdateProjectResponses, + UpdateStatusData, + UpdateStatusErrors, + UpdateStatusResponses, +} from "./types.gen"; +import { + zCreateBoardData, + zCreateBoardResponse2, + zCreateProjectData, + zCreateProjectResponse2, + zCreateStatusData, + zCreateStatusResponse2, + zDeleteBoardData, + zDeleteBoardResponse2, + zDeleteProjectData, + zDeleteProjectResponse2, + zDeleteStatusData, + zDeleteStatusResponse2, + zGetBoardsData, + zGetBoardsResponse2, + zGetDealsData, + zGetDealsResponse2, + zGetProjectsData, + zGetProjectsResponse2, + zGetStatusesData, + zGetStatusesResponse2, + zUpdateBoardData, + zUpdateBoardResponse2, + zUpdateDealData, + zUpdateDealResponse2, + zUpdateProjectData, + zUpdateProjectResponse2, + zUpdateStatusData, + zUpdateStatusResponse2, +} from "./zod.gen"; -export type Options = ClientOptions & { +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, +> = ClientOptions & { /** * You can provide a client instance returned by `createClient()` instead of * individual options. This might be also useful if you want to implement a @@ -22,206 +96,349 @@ export type Options(options: Options) => { - return (options.client ?? _heyApiClient).get({ - requestValidator: async (data) => { +export const getBoards = ( + options: Options +) => { + return (options.client ?? _heyApiClient).get< + GetBoardsResponses, + GetBoardsErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zGetBoardsData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zGetBoardsResponse2.parseAsync(data); }, - url: '/board/{projectId}', - ...options + url: "/board/{projectId}", + ...options, }); }; /** * Create Board */ -export const createBoard = (options: Options) => { - return (options.client ?? _heyApiClient).post({ - requestValidator: async (data) => { +export const createBoard = ( + options: Options +) => { + return (options.client ?? _heyApiClient).post< + CreateBoardResponses, + CreateBoardErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zCreateBoardData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zCreateBoardResponse2.parseAsync(data); }, - url: '/board/', + url: "/board/", ...options, headers: { - 'Content-Type': 'application/json', - ...options.headers - } + "Content-Type": "application/json", + ...options.headers, + }, }); }; /** * Delete Board */ -export const deleteBoard = (options: Options) => { - return (options.client ?? _heyApiClient).delete({ - requestValidator: async (data) => { +export const deleteBoard = ( + options: Options +) => { + return (options.client ?? _heyApiClient).delete< + DeleteBoardResponses, + DeleteBoardErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zDeleteBoardData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zDeleteBoardResponse2.parseAsync(data); }, - url: '/board/{boardId}', - ...options + url: "/board/{boardId}", + ...options, }); }; /** * Update Board */ -export const updateBoard = (options: Options) => { - return (options.client ?? _heyApiClient).patch({ - requestValidator: async (data) => { +export const updateBoard = ( + options: Options +) => { + return (options.client ?? _heyApiClient).patch< + UpdateBoardResponses, + UpdateBoardErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zUpdateBoardData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zUpdateBoardResponse2.parseAsync(data); }, - url: '/board/{boardId}', + url: "/board/{boardId}", ...options, headers: { - 'Content-Type': 'application/json', - ...options.headers - } + "Content-Type": "application/json", + ...options.headers, + }, }); }; /** * Get Deals */ -export const getDeals = (options: Options) => { - return (options.client ?? _heyApiClient).get({ - requestValidator: async (data) => { +export const getDeals = ( + options: Options +) => { + return (options.client ?? _heyApiClient).get< + GetDealsResponses, + GetDealsErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zGetDealsData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zGetDealsResponse2.parseAsync(data); }, - url: '/deal/{boardId}', - ...options + url: "/deal/{boardId}", + ...options, }); }; /** * Update Deal */ -export const updateDeal = (options: Options) => { - return (options.client ?? _heyApiClient).patch({ - requestValidator: async (data) => { +export const updateDeal = ( + options: Options +) => { + return (options.client ?? _heyApiClient).patch< + UpdateDealResponses, + UpdateDealErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zUpdateDealData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zUpdateDealResponse2.parseAsync(data); }, - url: '/deal/{dealId}', + url: "/deal/{dealId}", ...options, headers: { - 'Content-Type': 'application/json', - ...options.headers - } + "Content-Type": "application/json", + ...options.headers, + }, }); }; /** * Get Projects */ -export const getProjects = (options?: Options) => { - return (options?.client ?? _heyApiClient).get({ - requestValidator: async (data) => { +export const getProjects = ( + options?: Options +) => { + return (options?.client ?? _heyApiClient).get< + GetProjectsResponses, + unknown, + ThrowOnError + >({ + requestValidator: async data => { return await zGetProjectsData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zGetProjectsResponse2.parseAsync(data); }, - url: '/project/', - ...options + url: "/project/", + ...options, + }); +}; + +/** + * Create Project + */ +export const createProject = ( + options: Options +) => { + return (options.client ?? _heyApiClient).post< + CreateProjectResponses, + CreateProjectErrors, + ThrowOnError + >({ + requestValidator: async data => { + return await zCreateProjectData.parseAsync(data); + }, + responseType: "json", + responseValidator: async data => { + return await zCreateProjectResponse2.parseAsync(data); + }, + url: "/project/", + ...options, + headers: { + "Content-Type": "application/json", + ...options.headers, + }, + }); +}; + +/** + * Delete Project + */ +export const deleteProject = ( + options: Options +) => { + return (options.client ?? _heyApiClient).delete< + DeleteProjectResponses, + DeleteProjectErrors, + ThrowOnError + >({ + requestValidator: async data => { + return await zDeleteProjectData.parseAsync(data); + }, + responseType: "json", + responseValidator: async data => { + return await zDeleteProjectResponse2.parseAsync(data); + }, + url: "/project/{projectId}", + ...options, + }); +}; + +/** + * Update Project + */ +export const updateProject = ( + options: Options +) => { + return (options.client ?? _heyApiClient).patch< + UpdateProjectResponses, + UpdateProjectErrors, + ThrowOnError + >({ + requestValidator: async data => { + return await zUpdateProjectData.parseAsync(data); + }, + responseType: "json", + responseValidator: async data => { + return await zUpdateProjectResponse2.parseAsync(data); + }, + url: "/project/{projectId}", + ...options, + headers: { + "Content-Type": "application/json", + ...options.headers, + }, }); }; /** * Get Statuses */ -export const getStatuses = (options: Options) => { - return (options.client ?? _heyApiClient).get({ - requestValidator: async (data) => { +export const getStatuses = ( + options: Options +) => { + return (options.client ?? _heyApiClient).get< + GetStatusesResponses, + GetStatusesErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zGetStatusesData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zGetStatusesResponse2.parseAsync(data); }, - url: '/status/{boardId}', - ...options + url: "/status/{boardId}", + ...options, }); }; /** * Create Status */ -export const createStatus = (options: Options) => { - return (options.client ?? _heyApiClient).post({ - requestValidator: async (data) => { +export const createStatus = ( + options: Options +) => { + return (options.client ?? _heyApiClient).post< + CreateStatusResponses, + CreateStatusErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zCreateStatusData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zCreateStatusResponse2.parseAsync(data); }, - url: '/status/', + url: "/status/", ...options, headers: { - 'Content-Type': 'application/json', - ...options.headers - } + "Content-Type": "application/json", + ...options.headers, + }, }); }; /** * Delete Status */ -export const deleteStatus = (options: Options) => { - return (options.client ?? _heyApiClient).delete({ - requestValidator: async (data) => { +export const deleteStatus = ( + options: Options +) => { + return (options.client ?? _heyApiClient).delete< + DeleteStatusResponses, + DeleteStatusErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zDeleteStatusData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zDeleteStatusResponse2.parseAsync(data); }, - url: '/status/{statusId}', - ...options + url: "/status/{statusId}", + ...options, }); }; /** * Update Status */ -export const updateStatus = (options: Options) => { - return (options.client ?? _heyApiClient).patch({ - requestValidator: async (data) => { +export const updateStatus = ( + options: Options +) => { + return (options.client ?? _heyApiClient).patch< + UpdateStatusResponses, + UpdateStatusErrors, + ThrowOnError + >({ + requestValidator: async data => { return await zUpdateStatusData.parseAsync(data); }, - responseType: 'json', - responseValidator: async (data) => { + responseType: "json", + responseValidator: async data => { return await zUpdateStatusResponse2.parseAsync(data); }, - url: '/status/{statusId}', + url: "/status/{statusId}", ...options, headers: { - 'Content-Type': 'application/json', - ...options.headers - } + "Content-Type": "application/json", + ...options.headers, + }, }); -}; \ No newline at end of file +}; diff --git a/src/lib/client/types.gen.ts b/src/lib/client/types.gen.ts index 9e3420d..cbbbc9a 100644 --- a/src/lib/client/types.gen.ts +++ b/src/lib/client/types.gen.ts @@ -54,6 +54,34 @@ export type CreateBoardSchema = { lexorank: string; }; +/** + * CreateProjectRequest + */ +export type CreateProjectRequest = { + project: CreateProjectSchema; +}; + +/** + * CreateProjectResponse + */ +export type CreateProjectResponse = { + /** + * Message + */ + message: string; + project: ProjectSchema; +}; + +/** + * CreateProjectSchema + */ +export type CreateProjectSchema = { + /** + * Name + */ + name: string; +}; + /** * CreateStatusRequest */ @@ -122,6 +150,16 @@ export type DeleteBoardResponse = { message: string; }; +/** + * DeleteProjectResponse + */ +export type DeleteProjectResponse = { + /** + * Message + */ + message: string; +}; + /** * DeleteStatusResponse */ @@ -186,14 +224,14 @@ export type HttpValidationError = { * ProjectSchema */ export type ProjectSchema = { - /** - * Name - */ - name: string; /** * Id */ id: number; + /** + * Name + */ + name: string; }; /** @@ -280,6 +318,33 @@ export type UpdateDealSchema = { statusId?: number | null; }; +/** + * UpdateProjectRequest + */ +export type UpdateProjectRequest = { + project: UpdateProjectSchema; +}; + +/** + * UpdateProjectResponse + */ +export type UpdateProjectResponse = { + /** + * Message + */ + message: string; +}; + +/** + * UpdateProjectSchema + */ +export type UpdateProjectSchema = { + /** + * Name + */ + name?: string | null; +}; + /** * UpdateStatusRequest */ @@ -338,7 +403,7 @@ export type GetBoardsData = { projectId: number; }; query?: never; - url: '/board/{projectId}'; + url: "/board/{projectId}"; }; export type GetBoardsErrors = { @@ -363,7 +428,7 @@ export type CreateBoardData = { body: CreateBoardRequest; path?: never; query?: never; - url: '/board/'; + url: "/board/"; }; export type CreateBoardErrors = { @@ -382,7 +447,8 @@ export type CreateBoardResponses = { 200: CreateBoardResponse; }; -export type CreateBoardResponse2 = CreateBoardResponses[keyof CreateBoardResponses]; +export type CreateBoardResponse2 = + CreateBoardResponses[keyof CreateBoardResponses]; export type DeleteBoardData = { body?: never; @@ -393,7 +459,7 @@ export type DeleteBoardData = { boardId: number; }; query?: never; - url: '/board/{boardId}'; + url: "/board/{boardId}"; }; export type DeleteBoardErrors = { @@ -412,7 +478,8 @@ export type DeleteBoardResponses = { 200: DeleteBoardResponse; }; -export type DeleteBoardResponse2 = DeleteBoardResponses[keyof DeleteBoardResponses]; +export type DeleteBoardResponse2 = + DeleteBoardResponses[keyof DeleteBoardResponses]; export type UpdateBoardData = { body: UpdateBoardRequest; @@ -423,7 +490,7 @@ export type UpdateBoardData = { boardId: number; }; query?: never; - url: '/board/{boardId}'; + url: "/board/{boardId}"; }; export type UpdateBoardErrors = { @@ -442,7 +509,8 @@ export type UpdateBoardResponses = { 200: UpdateBoardResponse; }; -export type UpdateBoardResponse2 = UpdateBoardResponses[keyof UpdateBoardResponses]; +export type UpdateBoardResponse2 = + UpdateBoardResponses[keyof UpdateBoardResponses]; export type GetDealsData = { body?: never; @@ -453,7 +521,7 @@ export type GetDealsData = { boardId: number; }; query?: never; - url: '/deal/{boardId}'; + url: "/deal/{boardId}"; }; export type GetDealsErrors = { @@ -483,7 +551,7 @@ export type UpdateDealData = { dealId: number; }; query?: never; - url: '/deal/{dealId}'; + url: "/deal/{dealId}"; }; export type UpdateDealErrors = { @@ -502,13 +570,14 @@ export type UpdateDealResponses = { 200: UpdateDealResponse; }; -export type UpdateDealResponse2 = UpdateDealResponses[keyof UpdateDealResponses]; +export type UpdateDealResponse2 = + UpdateDealResponses[keyof UpdateDealResponses]; export type GetProjectsData = { body?: never; path?: never; query?: never; - url: '/project/'; + url: "/project/"; }; export type GetProjectsResponses = { @@ -518,7 +587,96 @@ export type GetProjectsResponses = { 200: GetProjectsResponse; }; -export type GetProjectsResponse2 = GetProjectsResponses[keyof GetProjectsResponses]; +export type GetProjectsResponse2 = + GetProjectsResponses[keyof GetProjectsResponses]; + +export type CreateProjectData = { + body: CreateProjectRequest; + path?: never; + query?: never; + url: "/project/"; +}; + +export type CreateProjectErrors = { + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type CreateProjectError = CreateProjectErrors[keyof CreateProjectErrors]; + +export type CreateProjectResponses = { + /** + * Successful Response + */ + 200: CreateProjectResponse; +}; + +export type CreateProjectResponse2 = + CreateProjectResponses[keyof CreateProjectResponses]; + +export type DeleteProjectData = { + body?: never; + path?: never; + query: { + /** + * Projectid + */ + projectId: number; + }; + url: "/project/{projectId}"; +}; + +export type DeleteProjectErrors = { + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type DeleteProjectError = DeleteProjectErrors[keyof DeleteProjectErrors]; + +export type DeleteProjectResponses = { + /** + * Successful Response + */ + 200: DeleteProjectResponse; +}; + +export type DeleteProjectResponse2 = + DeleteProjectResponses[keyof DeleteProjectResponses]; + +export type UpdateProjectData = { + body: UpdateProjectRequest; + path?: never; + query: { + /** + * Projectid + */ + projectId: number; + }; + url: "/project/{projectId}"; +}; + +export type UpdateProjectErrors = { + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type UpdateProjectError = UpdateProjectErrors[keyof UpdateProjectErrors]; + +export type UpdateProjectResponses = { + /** + * Successful Response + */ + 200: UpdateProjectResponse; +}; + +export type UpdateProjectResponse2 = + UpdateProjectResponses[keyof UpdateProjectResponses]; export type GetStatusesData = { body?: never; @@ -529,7 +687,7 @@ export type GetStatusesData = { boardId: number; }; query?: never; - url: '/status/{boardId}'; + url: "/status/{boardId}"; }; export type GetStatusesErrors = { @@ -548,13 +706,14 @@ export type GetStatusesResponses = { 200: GetStatusesResponse; }; -export type GetStatusesResponse2 = GetStatusesResponses[keyof GetStatusesResponses]; +export type GetStatusesResponse2 = + GetStatusesResponses[keyof GetStatusesResponses]; export type CreateStatusData = { body: CreateStatusRequest; path?: never; query?: never; - url: '/status/'; + url: "/status/"; }; export type CreateStatusErrors = { @@ -573,7 +732,8 @@ export type CreateStatusResponses = { 200: CreateStatusResponse; }; -export type CreateStatusResponse2 = CreateStatusResponses[keyof CreateStatusResponses]; +export type CreateStatusResponse2 = + CreateStatusResponses[keyof CreateStatusResponses]; export type DeleteStatusData = { body?: never; @@ -584,7 +744,7 @@ export type DeleteStatusData = { statusId: number; }; query?: never; - url: '/status/{statusId}'; + url: "/status/{statusId}"; }; export type DeleteStatusErrors = { @@ -603,7 +763,8 @@ export type DeleteStatusResponses = { 200: DeleteStatusResponse; }; -export type DeleteStatusResponse2 = DeleteStatusResponses[keyof DeleteStatusResponses]; +export type DeleteStatusResponse2 = + DeleteStatusResponses[keyof DeleteStatusResponses]; export type UpdateStatusData = { body: UpdateStatusRequest; @@ -614,7 +775,7 @@ export type UpdateStatusData = { statusId: number; }; query?: never; - url: '/status/{statusId}'; + url: "/status/{statusId}"; }; export type UpdateStatusErrors = { @@ -633,8 +794,9 @@ export type UpdateStatusResponses = { 200: UpdateStatusResponse; }; -export type UpdateStatusResponse2 = UpdateStatusResponses[keyof UpdateStatusResponses]; +export type UpdateStatusResponse2 = + UpdateStatusResponses[keyof UpdateStatusResponses]; export type ClientOptions = { baseURL: `${string}://${string}/api` | (string & {}); -}; \ No newline at end of file +}; diff --git a/src/lib/client/zod.gen.ts b/src/lib/client/zod.gen.ts index 2e3308e..1c42287 100644 --- a/src/lib/client/zod.gen.ts +++ b/src/lib/client/zod.gen.ts @@ -1,6 +1,6 @@ // This file is auto-generated by @hey-api/openapi-ts -import { z } from 'zod'; +import { z } from "zod"; /** * BoardSchema @@ -8,7 +8,7 @@ import { z } from 'zod'; export const zBoardSchema = z.object({ id: z.int(), name: z.string(), - lexorank: z.string() + lexorank: z.string(), }); /** @@ -17,14 +17,14 @@ export const zBoardSchema = z.object({ export const zCreateBoardSchema = z.object({ name: z.string(), projectId: z.int(), - lexorank: z.string() + lexorank: z.string(), }); /** * CreateBoardRequest */ export const zCreateBoardRequest = z.object({ - board: zCreateBoardSchema + board: zCreateBoardSchema, }); /** @@ -32,7 +32,37 @@ export const zCreateBoardRequest = z.object({ */ export const zCreateBoardResponse = z.object({ message: z.string(), - board: zBoardSchema + board: zBoardSchema, +}); + +/** + * CreateProjectSchema + */ +export const zCreateProjectSchema = z.object({ + name: z.string(), +}); + +/** + * CreateProjectRequest + */ +export const zCreateProjectRequest = z.object({ + project: zCreateProjectSchema, +}); + +/** + * ProjectSchema + */ +export const zProjectSchema = z.object({ + id: z.int(), + name: z.string(), +}); + +/** + * CreateProjectResponse + */ +export const zCreateProjectResponse = z.object({ + message: z.string(), + project: zProjectSchema, }); /** @@ -41,14 +71,14 @@ export const zCreateBoardResponse = z.object({ export const zCreateStatusSchema = z.object({ name: z.string(), boardId: z.int(), - lexorank: z.string() + lexorank: z.string(), }); /** * CreateStatusRequest */ export const zCreateStatusRequest = z.object({ - status: zCreateStatusSchema + status: zCreateStatusSchema, }); /** @@ -57,7 +87,7 @@ export const zCreateStatusRequest = z.object({ export const zStatusSchema = z.object({ id: z.int(), name: z.string(), - lexorank: z.string() + lexorank: z.string(), }); /** @@ -65,7 +95,7 @@ export const zStatusSchema = z.object({ */ export const zCreateStatusResponse = z.object({ message: z.string(), - status: zStatusSchema + status: zStatusSchema, }); /** @@ -75,172 +105,168 @@ export const zDealSchema = z.object({ name: z.string(), id: z.int(), lexorank: z.string(), - statusId: z.int() + statusId: z.int(), }); /** * DeleteBoardResponse */ export const zDeleteBoardResponse = z.object({ - message: z.string() + message: z.string(), +}); + +/** + * DeleteProjectResponse + */ +export const zDeleteProjectResponse = z.object({ + message: z.string(), }); /** * DeleteStatusResponse */ export const zDeleteStatusResponse = z.object({ - message: z.string() + message: z.string(), }); /** * GetBoardsResponse */ export const zGetBoardsResponse = z.object({ - boards: z.array(zBoardSchema) + boards: z.array(zBoardSchema), }); /** * GetDealsResponse */ export const zGetDealsResponse = z.object({ - deals: z.array(zDealSchema) -}); - -/** - * ProjectSchema - */ -export const zProjectSchema = z.object({ - name: z.string(), - id: z.int() + deals: z.array(zDealSchema), }); /** * GetProjectsResponse */ export const zGetProjectsResponse = z.object({ - projects: z.array(zProjectSchema) + projects: z.array(zProjectSchema), }); /** * GetStatusesResponse */ export const zGetStatusesResponse = z.object({ - statuses: z.array(zStatusSchema) + statuses: z.array(zStatusSchema), }); /** * ValidationError */ export const zValidationError = z.object({ - loc: z.array(z.union([ - z.string(), - z.int() - ])), + loc: z.array(z.union([z.string(), z.int()])), msg: z.string(), - type: z.string() + type: z.string(), }); /** * HTTPValidationError */ export const zHttpValidationError = z.object({ - detail: z.optional(z.array(zValidationError)) + detail: z.optional(z.array(zValidationError)), }); /** * UpdateBoardSchema */ export const zUpdateBoardSchema = z.object({ - name: z.optional(z.union([ - z.string(), - z.null() - ])), - lexorank: z.optional(z.union([ - z.string(), - z.null() - ])) + name: z.optional(z.union([z.string(), z.null()])), + lexorank: z.optional(z.union([z.string(), z.null()])), }); /** * UpdateBoardRequest */ export const zUpdateBoardRequest = z.object({ - board: zUpdateBoardSchema + board: zUpdateBoardSchema, }); /** * UpdateBoardResponse */ export const zUpdateBoardResponse = z.object({ - message: z.string() + message: z.string(), }); /** * UpdateDealSchema */ export const zUpdateDealSchema = z.object({ - name: z.optional(z.union([ - z.string(), - z.null() - ])), - lexorank: z.optional(z.union([ - z.string(), - z.null() - ])), - statusId: z.optional(z.union([ - z.int(), - z.null() - ])) + name: z.optional(z.union([z.string(), z.null()])), + lexorank: z.optional(z.union([z.string(), z.null()])), + statusId: z.optional(z.union([z.int(), z.null()])), }); /** * UpdateDealRequest */ export const zUpdateDealRequest = z.object({ - deal: zUpdateDealSchema + deal: zUpdateDealSchema, }); /** * UpdateDealResponse */ export const zUpdateDealResponse = z.object({ - message: z.string() + message: z.string(), +}); + +/** + * UpdateProjectSchema + */ +export const zUpdateProjectSchema = z.object({ + name: z.optional(z.union([z.string(), z.null()])), +}); + +/** + * UpdateProjectRequest + */ +export const zUpdateProjectRequest = z.object({ + project: zUpdateProjectSchema, +}); + +/** + * UpdateProjectResponse + */ +export const zUpdateProjectResponse = z.object({ + message: z.string(), }); /** * UpdateStatusSchema */ export const zUpdateStatusSchema = z.object({ - name: z.optional(z.union([ - z.string(), - z.null() - ])), - lexorank: z.optional(z.union([ - z.string(), - z.null() - ])) + name: z.optional(z.union([z.string(), z.null()])), + lexorank: z.optional(z.union([z.string(), z.null()])), }); /** * UpdateStatusRequest */ export const zUpdateStatusRequest = z.object({ - status: zUpdateStatusSchema + status: zUpdateStatusSchema, }); /** * UpdateStatusResponse */ export const zUpdateStatusResponse = z.object({ - message: z.string() + message: z.string(), }); export const zGetBoardsData = z.object({ body: z.optional(z.never()), path: z.object({ - projectId: z.int() + projectId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -251,7 +277,7 @@ export const zGetBoardsResponse2 = zGetBoardsResponse; export const zCreateBoardData = z.object({ body: zCreateBoardRequest, path: z.optional(z.never()), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -262,9 +288,9 @@ export const zCreateBoardResponse2 = zCreateBoardResponse; export const zDeleteBoardData = z.object({ body: z.optional(z.never()), path: z.object({ - boardId: z.int() + boardId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -275,9 +301,9 @@ export const zDeleteBoardResponse2 = zDeleteBoardResponse; export const zUpdateBoardData = z.object({ body: zUpdateBoardRequest, path: z.object({ - boardId: z.int() + boardId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -288,9 +314,9 @@ export const zUpdateBoardResponse2 = zUpdateBoardResponse; export const zGetDealsData = z.object({ body: z.optional(z.never()), path: z.object({ - boardId: z.int() + boardId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -301,9 +327,9 @@ export const zGetDealsResponse2 = zGetDealsResponse; export const zUpdateDealData = z.object({ body: zUpdateDealRequest, path: z.object({ - dealId: z.int() + dealId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -314,7 +340,7 @@ export const zUpdateDealResponse2 = zUpdateDealResponse; export const zGetProjectsData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -322,12 +348,49 @@ export const zGetProjectsData = z.object({ */ export const zGetProjectsResponse2 = zGetProjectsResponse; +export const zCreateProjectData = z.object({ + body: zCreateProjectRequest, + path: z.optional(z.never()), + query: z.optional(z.never()), +}); + +/** + * Successful Response + */ +export const zCreateProjectResponse2 = zCreateProjectResponse; + +export const zDeleteProjectData = z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.object({ + projectId: z.int(), + }), +}); + +/** + * Successful Response + */ +export const zDeleteProjectResponse2 = zDeleteProjectResponse; + +export const zUpdateProjectData = z.object({ + body: zUpdateProjectRequest, + path: z.optional(z.never()), + query: z.object({ + projectId: z.int(), + }), +}); + +/** + * Successful Response + */ +export const zUpdateProjectResponse2 = zUpdateProjectResponse; + export const zGetStatusesData = z.object({ body: z.optional(z.never()), path: z.object({ - boardId: z.int() + boardId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -338,7 +401,7 @@ export const zGetStatusesResponse2 = zGetStatusesResponse; export const zCreateStatusData = z.object({ body: zCreateStatusRequest, path: z.optional(z.never()), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -349,9 +412,9 @@ export const zCreateStatusResponse2 = zCreateStatusResponse; export const zDeleteStatusData = z.object({ body: z.optional(z.never()), path: z.object({ - statusId: z.int() + statusId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** @@ -362,12 +425,12 @@ export const zDeleteStatusResponse2 = zDeleteStatusResponse; export const zUpdateStatusData = z.object({ body: zUpdateStatusRequest, path: z.object({ - statusId: z.int() + statusId: z.int(), }), - query: z.optional(z.never()) + query: z.optional(z.never()), }); /** * Successful Response */ -export const zUpdateStatusResponse2 = zUpdateStatusResponse; \ No newline at end of file +export const zUpdateStatusResponse2 = zUpdateStatusResponse;