feat: Adds teams endpoints and zod validations

pull/9078/head
Agusti Fernandez Pardo 2022-03-26 01:53:56 +01:00
parent f2be36f89c
commit 8b8629f37a
6 changed files with 172 additions and 0 deletions

19
lib/validations/team.ts Normal file
View File

@ -0,0 +1,19 @@
import { withValidation } from "next-validations";
import { z } from "zod";
const schemaTeam = z
.object({
slug: z.string().min(3),
name: z.string().min(3),
hideBranding: z.boolean().default(false),
bio: z.string().min(3).optional(),
logo: z.string().optional(),
})
.strict(); // Adding strict so that we can disallow passing in extra fields
const withValidTeam = withValidation({
schema: schemaTeam,
type: "Zod",
mode: "body",
});
export { schemaTeam, withValidTeam };

View File

@ -0,0 +1,36 @@
import prisma from "@calcom/prisma";
import type { NextApiRequest, NextApiResponse } from "next";
import { schemaQueryId, withValidQueryIdTransformParseInt } from "@lib/validations/queryIdTransformParseInt";
type ResponseData = {
message?: string;
error?: unknown;
};
export async function team(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryId.safeParse(query);
if (safe.success) {
if (method === "DELETE") {
// DELETE WILL DELETE THE EVENT TYPE
prisma.team
.delete({ where: { id: safe.data.id } })
.then(() => {
// We only remove the team type from the database if there's an existing resource.
res.status(200).json({ message: `team-type with id: ${safe.data.id} deleted successfully` });
})
.catch((error) => {
// This catches the error thrown by prisma.team.delete() if the resource is not found.
res.status(400).json({ message: `Resource with id:${safe.data.id} was not found`, error: error });
});
} else {
// Reject any other HTTP method than POST
res.status(405).json({ message: "Only DELETE Method allowed in /team-types/[id]/delete endpoint" });
}
}
}
export default withValidQueryIdTransformParseInt(team);

View File

@ -0,0 +1,37 @@
import prisma from "@calcom/prisma";
import { Team } from "@calcom/prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
import { schemaTeam, withValidTeam } from "@lib/validations/team";
import { schemaQueryId, withValidQueryIdTransformParseInt } from "@lib/validations/queryIdTransformParseInt";
type ResponseData = {
data?: Team;
message?: string;
error?: unknown;
};
export async function editTeam(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, body, method } = req;
const safeQuery = await schemaQueryId.safeParse(query);
const safeBody = await schemaTeam.safeParse(body);
if (method === "PATCH") {
if (safeQuery.success && safeBody.success) {
await prisma.team.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
}).then(team => {
res.status(200).json({ data: team });
}).catch(error => {
res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error })
});
}
} else {
// Reject any other HTTP method than POST
res.status(405).json({ message: "Only PATCH Method allowed for updating team-types" });
}
}
export default withValidQueryIdTransformParseInt(withValidTeam(editTeam));

View File

@ -0,0 +1,31 @@
import prisma from "@calcom/prisma";
import { Team } from "@calcom/prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
import { schemaQueryId, withValidQueryIdTransformParseInt } from "@lib/validations/queryIdTransformParseInt";
type ResponseData = {
data?: Team;
message?: string;
error?: unknown;
};
export async function team(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryId.safeParse(query);
if (safe.success) {
if (method === "GET") {
const team = await prisma.team.findUnique({ where: { id: safe.data.id } });
if (team) res.status(200).json({ data: team });
if (!team) res.status(404).json({ message: "Event type not found" });
} else {
// Reject any other HTTP method than POST
res.status(405).json({ message: "Only GET Method allowed" });
}
}
}
export default withValidQueryIdTransformParseInt(team);

19
pages/api/team/index.ts Normal file
View File

@ -0,0 +1,19 @@
import prisma from "@calcom/prisma";
import { Team } from "@calcom/prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
type ResponseData = {
data?: Team[];
error?: unknown;
};
export default async function team(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
try {
const teams = await prisma.team.findMany();
res.status(200).json({ data: { ...teams } });
} catch (error) {
// FIXME: Add zod for validation/error handling
res.status(400).json({ error: error });
}
}

30
pages/api/team/new.ts Normal file
View File

@ -0,0 +1,30 @@
import prisma from "@calcom/prisma";
import { Team } from "@calcom/prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
import { schemaTeam, withValidTeam } from "@lib/validations/team";
type ResponseData = {
data?: Team;
message?: string;
error?: string;
};
async function createTeam(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { body, method } = req;
if (method === "POST") {
const safe = schemaTeam.safeParse(body);
if (safe.success && safe.data) {
await prisma.team
.create({ data: safe.data })
.then((team) => res.status(201).json({ data: team }))
.catch((error) => res.status(400).json({ message: "Could not create team", error: error }));
}
} else {
// Reject any other HTTP method than POST
res.status(405).json({ error: "Only POST Method allowed" });
}
}
export default withValidTeam(createTeam);