improve project controller typings

This commit is contained in:
João Geonizeli
2022-07-10 14:33:56 -03:00
parent 3816bb852c
commit e3729ae4c0
11 changed files with 129 additions and 79 deletions

View File

@@ -1,53 +1,68 @@
import { Router } from "express"; import { Router } from "express";
import { ProjectDto } from "../dto/poject.dto"; import { ProjectDto } from "../dto/poject.dto";
import { NewProjectDto } from "../dto/project.new.dto";
import { UpdateProjectDto } from "../dto/project.update.dto";
import { ProjectService } from "../service/project.service"; import { ProjectService } from "../service/project.service";
import {
CreateResponse, DeleteResponse, IndexResponse,
UpdateResponse
} from "./typings/responses";
const router = Router(); const router = Router();
export const ProjectRoutes = router; export const ProjectRoutes = router;
export const apiNamespace = "/projects"; export const apiNamespace = "/projects";
router.get(apiNamespace, async (req, res) => { router.get<typeof apiNamespace, IndexResponse<ProjectDto>>(
apiNamespace,
async (req, res) => {
const projects = await ProjectService.listAllByUserId(req.userId); const projects = await ProjectService.listAllByUserId(req.userId);
const response: ProjectDto[] = projects.map<ProjectDto>((project) => ({ res.json({
data: projects.map<ProjectDto>((project) => ({
id: project.id, id: project.id,
name: project.name, name: project.name,
})); })),
res.json({
data: response
});
}); });
}
);
router.post(apiNamespace, (req, res) => { router.post<typeof apiNamespace, unknown, CreateResponse<ProjectDto>, NewProjectDto>(
apiNamespace,
(req, res) => {
const { name } = req.body; const { name } = req.body;
ProjectService.create({ ProjectService.create(req.userId, {
name, name,
userId: req.userId,
}) })
.then((project) => { .then((project) => {
const respose: ProjectDto = { res.json({
data: {
id: project.id, id: project.id,
name: project.name, name: project.name,
}; },
});
res.json(respose);
}) })
.catch((err) => { .catch((err) => {
res.status(422).json({ res.status(422).json({
error: err.message, errors: [err.message],
});
}); });
}); });
}
);
router.put(`${apiNamespace}/:id`, async (req, res) => { const putPath = `${apiNamespace}/:taskId`;
const { id } = req.params; router.put<typeof putPath, { taskId: string }, UpdateResponse<ProjectDto>, UpdateProjectDto>(
putPath,
async (req, res) => {
const { taskId } = req.params;
const { name } = req.body; const { name } = req.body;
const projectId = parseInt(id); const projectId = parseInt(taskId);
const projectToBeUpdated = await ProjectService.findProjectFromUserById(req.userId, projectId); const projectToBeUpdated = await ProjectService.findProjectFromUserById(
req.userId,
projectId
);
if (projectToBeUpdated) { if (projectToBeUpdated) {
ProjectService.update(projectToBeUpdated, { ProjectService.update(projectToBeUpdated, {
@@ -61,16 +76,23 @@ router.put(`${apiNamespace}/:id`, async (req, res) => {
}); });
} else { } else {
res.status(404).json({ res.status(404).json({
error: "Project not found", errors: ["Project not found"],
}); });
} }
}); }
);
router.delete(`${apiNamespace}/:id`, async (req, res) => { const deletePath = `${apiNamespace}/:taskId`;
const { id } = req.params; router.delete<typeof deletePath, { taskId: string }, DeleteResponse>(
const projectId = parseInt(id); deletePath,
async (req, res) => {
const { taskId } = req.params;
const projectId = parseInt(taskId);
const projecToBeDeleted = await ProjectService.findProjectFromUserById(req.userId, projectId); const projecToBeDeleted = await ProjectService.findProjectFromUserById(
req.userId,
projectId
);
if (projecToBeDeleted) { if (projecToBeDeleted) {
const success = await ProjectService.destroy(projecToBeDeleted); const success = await ProjectService.destroy(projecToBeDeleted);
@@ -79,12 +101,13 @@ router.delete(`${apiNamespace}/:id`, async (req, res) => {
res.json({ success }); res.json({ success });
} else { } else {
res.status(422).json({ res.status(422).json({
error: "Could not delete project", errors: ["Could not delete project"],
}); });
} }
} else { } else {
res.status(404).json({ res.status(404).json({
error: "Project not found", errors: ["Project not found"],
}); });
} }
}); }
);

View File

@@ -0,0 +1,25 @@
export type ErrorResponse = {
errors: string[];
};
export type IndexResponse<TData> = {
data: TData[];
};
export type CreateResponse<TData> =
| {
data: TData;
}
| ErrorResponse;
export type UpdateResponse<TData> =
| {
data: TData;
}
| ErrorResponse;
export type DeleteResponse =
| {
success: boolean;
}
| ErrorResponse;

View File

@@ -1,4 +1,3 @@
export type NewProjectDto = { export type NewProjectDto = {
name: string name: string
userId: number
} }

View File

@@ -1,3 +1,3 @@
export type UpdateProjectDto = { export type UpdateProjectDto = {
name: string name?: string
} }

View File

@@ -1,14 +1,17 @@
import { validate } from "class-validator"; import { validate } from "class-validator";
import { NewProjectDto } from "../dto/newProject.dto"; import { NewProjectDto } from "../dto/project.new.dto";
import { UpdateProjectDto } from "../dto/updateProject.dto"; import { UpdateProjectDto } from "../dto/project.update.dto";
import { Project } from "../entity/project.entity"; import { Project } from "../entity/project.entity";
import { User } from "../entity/user.entity"; import { User } from "../entity/user.entity";
import { projectRepository } from "../repository/project.repository"; import { projectRepository } from "../repository/project.repository";
import { UserService } from "./user.service"; import { UserService } from "./user.service";
async function create(newProject: NewProjectDto): Promise<Project> { async function create(
userId: User["id"],
newProject: NewProjectDto
): Promise<Project> {
const project = new Project(); const project = new Project();
const user = await UserService.findUserById(newProject.userId); const user = await UserService.findUserById(userId);
project.name = newProject.name; project.name = newProject.name;
project.user = user; project.user = user;
@@ -40,9 +43,9 @@ async function destroy(project: Project): Promise<boolean> {
async function update( async function update(
project: Project, project: Project,
updateProjectDto: UpdateProjectDto data: UpdateProjectDto
): Promise<boolean> { ): Promise<boolean> {
projectRepository.merge(project, updateProjectDto); projectRepository.merge(project, data);
const updateResult = await projectRepository.save(project); const updateResult = await projectRepository.save(project);
return !!updateResult; return !!updateResult;
@@ -64,5 +67,5 @@ export const ProjectService = {
listAllByUserId, listAllByUserId,
destroy, destroy,
update, update,
findProjectFromUserById findProjectFromUserById,
}; };

View File

@@ -1,4 +1,4 @@
import { NewTaskDto } from "../dto/newTask.dto"; import { NewTaskDto } from "../dto/task.new.dto";
import { Project } from "../entity/project.entity"; import { Project } from "../entity/project.entity";
import { Task } from "../entity/task.entity"; import { Task } from "../entity/task.entity";
import { taskRepository } from "../repository/task.repository"; import { taskRepository } from "../repository/task.repository";

View File

@@ -1,5 +1,5 @@
import { validate } from "class-validator" import { validate } from "class-validator"
import { NewUserDto } from "../dto/newUser.dto" import { NewUserDto } from "../dto/user.new.dto"
import { User } from "../entity/user.entity" import { User } from "../entity/user.entity"
import { userRepository } from "../repository/user.repository" import { userRepository } from "../repository/user.repository"
import { AuthService } from "./auth.service" import { AuthService } from "./auth.service"