feat: add next-validations and zod validations

pull/9078/head
Agusti Fernandez Pardo 2022-03-24 21:25:35 +01:00
parent c5b12d46af
commit 713f53acc4
7 changed files with 114 additions and 98 deletions

View File

@ -29,6 +29,7 @@
},
"dependencies": {
"next": "^12.1.0",
"next-validations": "^0.1.11",
"zod": "^3.14.2"
}
}

View File

@ -1,19 +1,47 @@
import { PrismaClient, EventType } from "@prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
import { withValidation } from "next-validations";
import { z } from "zod";
import prisma from "@calcom/prisma";
import { EventType } from "@calcom/prisma/client";
const prisma = new PrismaClient();
type Data = {
event?: EventType;
const schema = z
.object({
id: z
.string()
.regex(/^\d+$/)
.transform((id) => parseInt(id)),
})
.strict();
const validate = withValidation({
schema,
type: "Zod",
mode: "query",
});
type ResponseData = {
data?: EventType;
error?: any;
};
export default async function eventType(req: NextApiRequest, res: NextApiResponse<Data>) {
try {
const event = await prisma.eventType.findUnique({ where: { id: Number(req.query.id) } });
res.status(200).json({ event });
} catch (error) {
console.log(error);
res.status(400).json({ error: error });
export async function eventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
if (method === "GET") {
const safe = await schema.safeParse(query);
if (safe.success) {
try {
const event = await prisma.eventType.findUnique({ where: { id: safe.data.id } });
res.status(200).json({ data: event });
} catch (error) {
console.log(error);
res.status(400).json({ error: error });
}
}
} else {
// Reject any other HTTP method than POST
res.status(405).json({ error: "Only GET Method allowed" });
}
}
export default validate(eventType);

View File

@ -1,17 +1,16 @@
import { PrismaClient, EventType } from "@prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { EventType } from "@calcom/prisma/client";
type Data = {
events?: EventType[];
const prisma = new PrismaClient();
type ResponseData = {
data?: EventType[];
error?: any;
};
export default async function eventType(req: NextApiRequest, res: NextApiResponse<Data>) {
export default async function eventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
try {
const eventTypes = await prisma.eventType.findMany({ where: { id: Number(req.query.eventTypeId) } });
res.status(200).json({ events: { ...eventTypes } });
res.status(200).json({ data: { ...eventTypes } });
} catch (error) {
console.log(error);
// FIXME: Add zod for validation/error handling

View File

@ -1,86 +1,49 @@
import { PrismaClient, EventType } from "@prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
import { withValidation } from "next-validations";
import { z } from "zod";
import prisma from "@calcom/prisma";
import { EventType } from "@calcom/prisma/client";
const prisma = new PrismaClient();
const schema = z
.object({
title: z.string().min(3),
slug: z.string().min(3),
length: z.number().min(1).max(1440), // max is a full day.
description: z.string().min(3).optional(),
})
.strict(); // Adding strict so that we can disallow passing in extra fields
const validate = withValidation({
schema,
type: "Zod",
mode: "body",
});
interface Body {
userId: string;
newOrganization: {
name: string;
users: string[];
};
title: string;
slug: string;
length: number;
}
type Data = {
event?: EventType;
data?: EventType;
error?: string;
};
export default async function createEventLink(req: NextApiRequest, res: NextApiResponse<Data>) {
const {
body: {
title,
slug,
description,
position,
locations,
hidden,
teamId,
eventName,
timeZone,
periodType,
periodStartDate,
periodEndDate,
periodDays,
periodCountCalendarDays,
requiresConfirmation,
disableGuests,
minimumBookingNotice,
beforeEventBuffer,
afterEventBuffer,
schedulingType,
price,
currency,
slotInterval,
metadata,
length,
},
method,
} = req;
type NextApiRequestWithBody = NextApiRequest & {
body: Body;
};
async function createEventType(req: NextApiRequestWithBody, res: NextApiResponse<Data>) {
const { body, method }: { body: Body; method?: string } = req;
if (method === "POST") {
// Process a POST request
const newEvent = await prisma.eventType.create({
data: {
title: `${title}`,
slug: `${slug}`,
length: Number(length),
// description: description as string,
// position: Number(position),
// locations: locations,
// hidden: Boolean(hidden) as boolean,
// teamId: Number.isInteger(teamId) ? Number(teamId) : null,
// eventName: eventName,
// timeZone: timeZone,
// periodType: periodType,
// periodStartDate: periodStartDate,
// periodEndDate: periodEndDate,
// periodDays: periodDays,
// periodCountCalendarDays: periodCountCalendarDays,
// requiresConfirmation: requiresConfirmation,
// disableGuests: disableGuests,
// minimumBookingNotice: minimumBookingNotice,
// beforeEventBuffer: beforeEventBuffer,
// afterEventBuffer: afterEventBuffer,
// schedulingType: schedulingType,
// price: price,
// currency: currency,
// slotInterval: slotInterval,
// metadata: metadata,
},
});
res.status(201).json({ event: newEvent });
schema.safeParse(body);
const newEvent = await prisma.eventType.create({ data: body });
res.status(201).json({ data: newEvent });
} else {
// Handle any other HTTP method
// Reject any other HTTP method than POST
res.status(405).json({ error: "Only POST Method allowed" });
}
}
export default validate(createEventType);

View File

@ -1,9 +1,7 @@
import { PrismaClient } from "@prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
// This local import doesn't work
// import { PrismaClient } from "@calcom/prisma";
const prisma = new PrismaClient();
import prisma from "@calcom/prisma";
import { User } from "@calcom/prisma/client";
type Data = {
message: string;

19
pages/api/users/valid.ts Normal file
View File

@ -0,0 +1,19 @@
import { NextApiRequest, NextApiResponse } from "next";
import { withValidation } from "next-validations";
import { z } from "zod";
const schema = z.object({
username: z.string().min(6),
});
const validate = withValidation({
schema,
type: "Zod",
mode: "body",
});
const handler = (req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json(req.body);
};
export default validate(handler);

View File

@ -4,12 +4,20 @@
"node_modules"
],
"compilerOptions": {
"lib": ["ES2015"],
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./",
"strictNullChecks": true,
"baseUrl": "./",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"noEmit": true,
"incremental": true,
"module": "esnext",
"resolveJsonModule": true,
"jsx": "preserve"
},
"include": [
"./pages/api/*.ts"