From 9afbb3d12789122dda820b38dd465a19527aa923 Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Mon, 16 May 2022 21:59:22 +0200 Subject: [PATCH 1/3] fix: event-type validations move to pick not omit and separate create/edit --- lib/validations/event-type.ts | 51 ++++++++++++++++++++++++++++------ pages/api/event-types/[id].ts | 8 +++--- pages/api/event-types/index.ts | 8 +++--- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/lib/validations/event-type.ts b/lib/validations/event-type.ts index e8665a9e3b..40411a7222 100644 --- a/lib/validations/event-type.ts +++ b/lib/validations/event-type.ts @@ -2,14 +2,49 @@ import { z } from "zod"; import { _EventTypeModel as EventType } from "@calcom/prisma/zod"; -export const schemaEventTypeBaseBodyParams = EventType.omit({ id: true }).partial(); +export const schemaEventTypeBaseBodyParams = EventType.pick({ + title: true, + slug: true, + length: true, +}).partial(); -const schemaEventTypeRequiredParams = z.object({ - title: z.string(), - slug: z.string(), - length: z.number(), +const schemaEventTypeCreateParams = z + .object({ + title: z.string(), + slug: z.string(), + length: z.number(), + }) + .strict(); + +export const schemaEventTypeCreateBodyParams = + schemaEventTypeBaseBodyParams.merge(schemaEventTypeCreateParams); + +const schemaEventTypeEditParams = z + .object({ + token: z.string().optional(), + url: z.string().optional(), + }) + .strict(); + +export const schemaEventTypeEditBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeEditParams); +export const schemaEventTypeReadPublic = EventType.pick({ + title: true, + slug: true, + length: true, }); -export const schemaEventTypeBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeRequiredParams); -// @NOTE: Removing locations and metadata properties before validation, add them later if required -export const schemaEventTypePublic = EventType.omit({ locations: true, metadata: true }); +// import { z } from "zod"; + +// import { _EventTypeModel as EventType } from "@calcom/prisma/zod"; + +// export const schemaEventTypeBaseBodyParams = EventType.omit({ id: true }).partial(); + +// const schemaEventTypeRequiredParams = z.object({ +// title: z.string(), +// slug: z.string(), +// length: z.number(), +// }); + +// export const schemaEventTypeBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeRequiredParams); +// // @NOTE: Removing locations and metadata properties before validation, add them later if required +// export const schemaEventTypePublic = EventType.omit({ locations: true, metadata: true }); diff --git a/pages/api/event-types/[id].ts b/pages/api/event-types/[id].ts index a6900b1d27..328e101b28 100644 --- a/pages/api/event-types/[id].ts +++ b/pages/api/event-types/[id].ts @@ -4,7 +4,7 @@ import prisma from "@calcom/prisma"; import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { EventTypeResponse } from "@lib/types"; -import { schemaEventTypeBodyParams, schemaEventTypePublic } from "@lib/validations/event-type"; +import { schemaEventTypeEditBodyParams, schemaEventTypeReadPublic } from "@lib/validations/event-type"; import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt, @@ -52,7 +52,7 @@ export async function eventTypeById( case "GET": await prisma.eventType .findUnique({ where: { id: safeQuery.data.id } }) - .then((data) => schemaEventTypePublic.parse(data)) + .then((data) => schemaEventTypeReadPublic.parse(data)) .then((event_type) => res.status(200).json({ event_type })) .catch((error: Error) => res.status(404).json({ @@ -89,13 +89,13 @@ export async function eventTypeById( * description: Authorization information is missing or invalid. */ case "PATCH": - const safeBody = schemaEventTypeBodyParams.safeParse(body); + const safeBody = schemaEventTypeEditBodyParams.safeParse(body); if (!safeBody.success) { throw new Error("Invalid request body"); } await prisma.eventType .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) - .then((data) => schemaEventTypePublic.parse(data)) + .then((data) => schemaEventTypeReadPublic.parse(data)) .then((event_type) => res.status(200).json({ event_type })) .catch((error: Error) => res.status(404).json({ diff --git a/pages/api/event-types/index.ts b/pages/api/event-types/index.ts index dad45eec42..1229785f50 100644 --- a/pages/api/event-types/index.ts +++ b/pages/api/event-types/index.ts @@ -4,7 +4,7 @@ import prisma from "@calcom/prisma"; import { withMiddleware } from "@lib/helpers/withMiddleware"; import { EventTypeResponse, EventTypesResponse } from "@lib/types"; -import { schemaEventTypeBodyParams, schemaEventTypePublic } from "@lib/validations/event-type"; +import { schemaEventTypeCreateBodyParams, schemaEventTypeReadPublic } from "@lib/validations/event-type"; async function createOrlistAllEventTypes( { method, body, userId }: NextApiRequest, @@ -29,7 +29,7 @@ async function createOrlistAllEventTypes( * description: No event types were found */ const data = await prisma.eventType.findMany({ where: { userId } }); - const event_types = data.map((eventType) => schemaEventTypePublic.parse(eventType)); + const event_types = data.map((eventType) => schemaEventTypeReadPublic.parse(eventType)); if (event_types) res.status(200).json({ event_types }); else (error: Error) => @@ -55,11 +55,11 @@ async function createOrlistAllEventTypes( * 401: * description: Authorization information is missing or invalid. */ - const safe = schemaEventTypeBodyParams.safeParse(body); + const safe = schemaEventTypeCreateBodyParams.safeParse(body); if (!safe.success) throw new Error("Invalid request body"); const data = await prisma.eventType.create({ data: { ...safe.data, userId } }); - const event_type = schemaEventTypePublic.parse(data); + const event_type = schemaEventTypeReadPublic.parse(data); if (data) res.status(201).json({ event_type, message: "EventType created successfully" }); else From 3366627835bc30bd575f625ced5743878fd73b37 Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Tue, 17 May 2022 14:40:19 +0200 Subject: [PATCH 2/3] fix: event-type params --- lib/validations/event-type.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/validations/event-type.ts b/lib/validations/event-type.ts index 40411a7222..aa66cc63dd 100644 --- a/lib/validations/event-type.ts +++ b/lib/validations/event-type.ts @@ -21,8 +21,9 @@ export const schemaEventTypeCreateBodyParams = const schemaEventTypeEditParams = z .object({ - token: z.string().optional(), - url: z.string().optional(), + title: z.string().optional(), + slug: z.string().optional(), + length: z.number().optional(), }) .strict(); From 5aa0b3744373fc8cd208d2fc4199f3ad820bd91d Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Tue, 17 May 2022 19:33:18 +0200 Subject: [PATCH 3/3] fix build and pass lint --- README.md | 30 ++++----- lib/validations/event-type.ts | 85 ++++++++++++++++++------ lib/validations/user.ts | 5 ++ package.json | 4 +- pages/api/booking-references/[id].ts | 1 - pages/api/booking-references/index.ts | 10 --- pages/api/bookings/[id].ts | 1 - pages/api/bookings/index.ts | 1 - pages/api/custom-inputs/[id].ts | 5 +- pages/api/custom-inputs/index.ts | 5 +- pages/api/destination-calendars/[id].ts | 5 +- pages/api/destination-calendars/index.ts | 5 +- pages/api/event-references/[id].ts | 5 +- pages/api/event-references/index.ts | 5 +- pages/api/event-types/[id].ts | 5 +- pages/api/event-types/index.ts | 32 ++++++++- pages/api/hooks/[id].ts | 5 +- pages/api/hooks/index.ts | 5 +- pages/api/memberships/[id].ts | 5 +- pages/api/memberships/index.ts | 5 +- pages/api/schedules/[id].ts | 5 +- pages/api/schedules/index.ts | 5 +- pages/api/selected-calendars/[id].ts | 5 +- pages/api/selected-calendars/index.ts | 5 +- pages/api/teams/[id].ts | 5 +- pages/api/teams/index.ts | 5 +- pages/api/users/[id].ts | 2 +- templates/endpoints/get_all_and_post.ts | 5 +- templates/endpoints/post.ts | 5 +- types.d.ts | 1 - 30 files changed, 193 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index d210672e53..8c39f8457f 100644 --- a/README.md +++ b/README.md @@ -120,21 +120,21 @@ We aim to provide a fully tested API for our peace of mind, this is accomplished ## Endpoints matrix -| resource | get [id] | get all | create | edit | delete | -| ------------------------ | -------- | ------- | ------ | ---- | ------ | -| attendees | ✅ | ✅ | ✅ | ✅ | ✅ | -| availabilities | ✅ | ✅ | ✅ | ✅ | ✅ | -| booking-references | ✅ | ✅ | ✅ | ✅ | ✅ | -| event-references | ✅ | ✅ | ✅ | ✅ | ✅ | -| destination-calendars | ✅ | ✅ | ✅ | ✅ | ✅ | -| custom-inputs | ✅ | ✅ | ✅ | ✅ | ✅ | -| event-types | ✅ | ✅ | ✅ | ✅ | ✅ | -| memberships | ✅ | ✅ | ✅ | ✅ | ✅ | -| payments | ✅ | ✅ | ❌ | ❌ | ❌ | -| schedules | ✅ | ✅ | ✅ | ✅ | ✅ | -| selected-calendars | ✅ | ✅ | ✅ | ✅ | ✅ | -| teams | ✅ | ✅ | ✅ | ✅ | ✅ | -| users | ✅ | 👤[1] | ✅ | ✅ | ✅ | +| resource | get [id] | get all | create | edit | delete | +| --------------------- | -------- | ------- | ------ | ---- | ------ | +| attendees | ✅ | ✅ | ✅ | ✅ | ✅ | +| availabilities | ✅ | ✅ | ✅ | ✅ | ✅ | +| booking-references | ✅ | ✅ | ✅ | ✅ | ✅ | +| event-references | ✅ | ✅ | ✅ | ✅ | ✅ | +| destination-calendars | ✅ | ✅ | ✅ | ✅ | ✅ | +| custom-inputs | ✅ | ✅ | ✅ | ✅ | ✅ | +| event-types | ✅ | ✅ | ✅ | ✅ | ✅ | +| memberships | ✅ | ✅ | ✅ | ✅ | ✅ | +| payments | ✅ | ✅ | ❌ | ❌ | ❌ | +| schedules | ✅ | ✅ | ✅ | ✅ | ✅ | +| selected-calendars | ✅ | ✅ | ✅ | ✅ | ✅ | +| teams | ✅ | ✅ | ✅ | ✅ | ✅ | +| users | ✅ | 👤[1] | ✅ | ✅ | ✅ | ## Models from database that are not exposed diff --git a/lib/validations/event-type.ts b/lib/validations/event-type.ts index aa66cc63dd..25bb87491d 100644 --- a/lib/validations/event-type.ts +++ b/lib/validations/event-type.ts @@ -1,51 +1,92 @@ import { z } from "zod"; import { _EventTypeModel as EventType } from "@calcom/prisma/zod"; +import { eventTypeLocations, recurringEvent } from "@calcom/prisma/zod-utils"; + +import { jsonSchema } from "./shared/jsonSchema"; export const schemaEventTypeBaseBodyParams = EventType.pick({ title: true, slug: true, length: true, + hidden: true, + position: true, + userId: true, + teamId: true, + eventName: true, + timeZone: true, + periodType: true, + periodStartDate: true, + periodEndDate: true, + periodDays: true, + periodCountCalendarDays: true, + requiresConfirmation: true, + disableGuests: true, + hideCalendarNotes: true, + minimumBookingNotice: true, + beforeEventBuffer: true, + afterEventBuffer: true, + schedulingType: true, + price: true, + currency: true, + slotInterval: true, + metadata: true, + successRedirectUrl: true, }).partial(); -const schemaEventTypeCreateParams = z +const schemaEventTypeBaseParams = z .object({ title: z.string(), slug: z.string(), - length: z.number(), + description: z.string().optional().nullable(), + length: z.number().int(), + locations: jsonSchema, + metadata: jsonSchema, + recurringEvent: jsonSchema, }) .strict(); -export const schemaEventTypeCreateBodyParams = - schemaEventTypeBaseBodyParams.merge(schemaEventTypeCreateParams); +export const schemaEventTypeCreateBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeBaseParams); const schemaEventTypeEditParams = z .object({ title: z.string().optional(), slug: z.string().optional(), - length: z.number().optional(), + length: z.number().int().optional(), }) .strict(); export const schemaEventTypeEditBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeEditParams); export const schemaEventTypeReadPublic = EventType.pick({ + id: true, title: true, slug: true, length: true, -}); - -// import { z } from "zod"; - -// import { _EventTypeModel as EventType } from "@calcom/prisma/zod"; - -// export const schemaEventTypeBaseBodyParams = EventType.omit({ id: true }).partial(); - -// const schemaEventTypeRequiredParams = z.object({ -// title: z.string(), -// slug: z.string(), -// length: z.number(), -// }); - -// export const schemaEventTypeBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeRequiredParams); -// // @NOTE: Removing locations and metadata properties before validation, add them later if required -// export const schemaEventTypePublic = EventType.omit({ locations: true, metadata: true }); + locations: true, + hidden: true, + position: true, + userId: true, + teamId: true, + eventName: true, + timeZone: true, + periodType: true, + periodStartDate: true, + periodEndDate: true, + periodDays: true, + periodCountCalendarDays: true, + requiresConfirmation: true, + recurringEvent: true, + disableGuests: true, + hideCalendarNotes: true, + minimumBookingNotice: true, + beforeEventBuffer: true, + afterEventBuffer: true, + schedulingType: true, + price: true, + currency: true, + slotInterval: true, + metadata: true, + successRedirectUrl: true, +}) + .merge(schemaEventTypeBaseParams) + .partial(); diff --git a/lib/validations/user.ts b/lib/validations/user.ts index b70d52f898..d78d8e23b2 100644 --- a/lib/validations/user.ts +++ b/lib/validations/user.ts @@ -4,6 +4,8 @@ import { _UserModel as User } from "@calcom/prisma/zod"; import { timeZone } from "@lib/validations/shared/timeZone"; +import { jsonSchema } from "./shared/jsonSchema"; + // @note: These are the ONLY values allowed as weekStart. So user don't introduce bad data. enum weekdays { MONDAY = "Monday", @@ -57,6 +59,7 @@ export const schemaUserBaseBodyParams = User.pick({ timeZone: true, weekStart: true, endTime: true, + metadata: true, bufferTime: true, theme: true, defaultScheduleId: true, @@ -89,6 +92,7 @@ const schemaUserEditParams = z.object({ .refine((id: number) => id > 0) .optional(), locale: z.nativeEnum(locales).optional(), + metadata: jsonSchema, }); // @note: These are the values that are editable via PATCH method on the user Model, @@ -104,6 +108,7 @@ export const schemaUserReadPublic = User.pick({ emailVerified: true, bio: true, avatar: true, + metadata: true, timeZone: true, weekStart: true, endTime: true, diff --git a/package.json b/package.json index 14c34d18af..143065b933 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,4 @@ - { +{ "name": "@calcom/api", "version": "1.0.0", "description": "Public API for Cal.com", @@ -8,7 +8,7 @@ "private": true, "scripts": { "dev": "next build && PORT=3002 next start", - "dev-real":"PORT=3002 next dev", + "dev-real": "PORT=3002 next dev", "start": "PORT=3002 next start", "build": "next build", "lint": "next lint", diff --git a/pages/api/booking-references/[id].ts b/pages/api/booking-references/[id].ts index d1c28b8d04..8041617bb3 100644 --- a/pages/api/booking-references/[id].ts +++ b/pages/api/booking-references/[id].ts @@ -132,7 +132,6 @@ export async function bookingReferenceById( console.log(safeBody.error); res.status(400).json({ message: "Invalid request body", error: safeBody.error }); return; - // throw new Error("Invalid request body"); } await prisma.bookingReference .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/booking-references/index.ts b/pages/api/booking-references/index.ts index 3386d5e42d..58e45d5c9e 100644 --- a/pages/api/booking-references/index.ts +++ b/pages/api/booking-references/index.ts @@ -97,17 +97,7 @@ async function createOrlistAllBookingReferences( if (!safe.success) { res.status(400).json({ message: "Bad request. BookingReference body is invalid", error: safe.error }); return; - // throw new Error("Invalid request body"); } - - const userWithBookings = await prisma.user.findUnique({ - where: { id: userId }, - include: { bookings: true }, - }); - if (!userWithBookings) { - throw new Error("User not found"); - } - const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat(); if (!safe.data.bookingId) throw new Error("BookingReference: bookingId not found"); if (!userBookingIds.includes(safe.data.bookingId)) res.status(401).json({ message: "Unauthorized" }); else { diff --git a/pages/api/bookings/[id].ts b/pages/api/bookings/[id].ts index b094df73e9..b6a37122c1 100644 --- a/pages/api/bookings/[id].ts +++ b/pages/api/bookings/[id].ts @@ -106,7 +106,6 @@ export async function bookingById( console.log(safeBody.error); res.status(400).json({ message: "Bad request", error: safeBody.error }); return; - // throw new Error("Invalid request body"); } await prisma.booking .update({ diff --git a/pages/api/bookings/index.ts b/pages/api/bookings/index.ts index 00b92932a7..40f24283ee 100644 --- a/pages/api/bookings/index.ts +++ b/pages/api/bookings/index.ts @@ -76,7 +76,6 @@ async function createOrlistAllBookings( console.log(safe.error); res.status(400).json({ message: "Bad request. Booking body is invalid." }); return; - // throw new Error("Invalid request body"); } safe.data.userId = userId; const data = await prisma.booking.create({ data: { ...safe.data } }); diff --git a/pages/api/custom-inputs/[id].ts b/pages/api/custom-inputs/[id].ts index eb5493235f..8c20771a45 100644 --- a/pages/api/custom-inputs/[id].ts +++ b/pages/api/custom-inputs/[id].ts @@ -105,7 +105,10 @@ async function eventTypeById( case "PATCH": if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.eventTypeCustomInput .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/custom-inputs/index.ts b/pages/api/custom-inputs/index.ts index c7d5f9df90..e1c2d484ed 100644 --- a/pages/api/custom-inputs/index.ts +++ b/pages/api/custom-inputs/index.ts @@ -59,7 +59,10 @@ async function createOrlistAllEventTypeCustomInputs( * description: Authorization information is missing or invalid. */ const safe = schemaEventTypeCustomInputBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } // Since we're supporting a create or connect relation on eventType, we need to treat them differently // When using connect on event type, check if userId is the owner of the event if (safe.data.eventType.connect && !userEventTypes.includes(safe.data.eventType.connect.id as number)) { diff --git a/pages/api/destination-calendars/[id].ts b/pages/api/destination-calendars/[id].ts index 60e8aae6b3..675f8c2e28 100644 --- a/pages/api/destination-calendars/[id].ts +++ b/pages/api/destination-calendars/[id].ts @@ -121,7 +121,10 @@ export async function destionationCalendarById( */ case "PATCH": if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.destinationCalendar .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/destination-calendars/index.ts b/pages/api/destination-calendars/index.ts index 4006a67c72..bfd7df6d89 100644 --- a/pages/api/destination-calendars/index.ts +++ b/pages/api/destination-calendars/index.ts @@ -57,7 +57,10 @@ async function createOrlistAllDestinationCalendars( * description: Authorization information is missing or invalid. */ const safe = schemaDestinationCalendarCreateBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const data = await prisma.destinationCalendar.create({ data: { ...safe.data, userId } }); const destination_calendar = schemaDestinationCalendarReadPublic.parse(data); diff --git a/pages/api/event-references/[id].ts b/pages/api/event-references/[id].ts index 03ee39f49e..97bb53bc82 100644 --- a/pages/api/event-references/[id].ts +++ b/pages/api/event-references/[id].ts @@ -93,7 +93,10 @@ export async function dailyEventReferenceById( */ case "PATCH": if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.dailyEventReference .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/event-references/index.ts b/pages/api/event-references/index.ts index e0b18a7919..48a438e321 100644 --- a/pages/api/event-references/index.ts +++ b/pages/api/event-references/index.ts @@ -64,7 +64,10 @@ async function createOrlistAllDailyEventReferences( * description: Authorization information is missing or invalid. */ const safe = schemaDailyEventReferenceCreateBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const data = await prisma.dailyEventReference.create({ data: safe.data }); const daily_event_reference = schemaDailyEventReferenceReadPublic.parse(data); diff --git a/pages/api/event-types/[id].ts b/pages/api/event-types/[id].ts index 328e101b28..224a7c9995 100644 --- a/pages/api/event-types/[id].ts +++ b/pages/api/event-types/[id].ts @@ -91,7 +91,10 @@ export async function eventTypeById( case "PATCH": const safeBody = schemaEventTypeEditBodyParams.safeParse(body); if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.eventType .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/event-types/index.ts b/pages/api/event-types/index.ts index 1229785f50..163fa501fb 100644 --- a/pages/api/event-types/index.ts +++ b/pages/api/event-types/index.ts @@ -16,6 +16,7 @@ async function createOrlistAllEventTypes( * /event-types: * get: * summary: Find all event types + * operationId: listEventTypes * tags: * - event-types * externalDocs: @@ -43,6 +44,32 @@ async function createOrlistAllEventTypes( * /event-types: * post: * summary: Creates a new event type + * operationId: addEventType + * requestBody: + * description: Create a new event-type related to your user or team + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - title + * - slug + * - length + * - metadata + * properties: + * length: + * type: number + * example: 30 + * metadata: + * type: object + * example: {"smartContractAddress": "0x1234567890123456789012345678901234567890"} + * title: + * type: string + * example: My Event + * slug: + * type: string + * example: my-event * tags: * - event-types * externalDocs: @@ -56,7 +83,10 @@ async function createOrlistAllEventTypes( * description: Authorization information is missing or invalid. */ const safe = schemaEventTypeCreateBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body", error: safe.error }); + return; + } const data = await prisma.eventType.create({ data: { ...safe.data, userId } }); const event_type = schemaEventTypeReadPublic.parse(data); diff --git a/pages/api/hooks/[id].ts b/pages/api/hooks/[id].ts index 59ae3e3516..cc017d8e8f 100644 --- a/pages/api/hooks/[id].ts +++ b/pages/api/hooks/[id].ts @@ -85,7 +85,10 @@ export async function WebhookById( case "PATCH": const safeBody = schemaWebhookEditBodyParams.safeParse(body); if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.webhook .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/hooks/index.ts b/pages/api/hooks/index.ts index 9ce8615ea7..ccda5dcd76 100644 --- a/pages/api/hooks/index.ts +++ b/pages/api/hooks/index.ts @@ -56,7 +56,10 @@ async function createOrlistAllWebhooks( * description: Authorization information is missing or invalid. */ const safe = schemaWebhookCreateBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const data = await prisma.webhook.create({ data: { ...safe.data, userId } }); const webhook = schemaWebhookReadPublic.parse(data); diff --git a/pages/api/memberships/[id].ts b/pages/api/memberships/[id].ts index 0681a629a9..1b9ceaada8 100644 --- a/pages/api/memberships/[id].ts +++ b/pages/api/memberships/[id].ts @@ -97,7 +97,10 @@ export async function membershipById( case "PATCH": const safeBody = schemaMembershipBodyParams.safeParse(body); if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.membership .update({ diff --git a/pages/api/memberships/index.ts b/pages/api/memberships/index.ts index 2000ed84e3..efd3fb278c 100644 --- a/pages/api/memberships/index.ts +++ b/pages/api/memberships/index.ts @@ -52,7 +52,10 @@ async function createOrlistAllMemberships( * description: Authorization information is missing or invalid. */ const safe = schemaMembershipBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const data = await prisma.membership.create({ data: { ...safe.data, userId } }); const membership = schemaMembershipPublic.parse(data); diff --git a/pages/api/schedules/[id].ts b/pages/api/schedules/[id].ts index 5b90027ac3..a6e65a87a3 100644 --- a/pages/api/schedules/[id].ts +++ b/pages/api/schedules/[id].ts @@ -83,7 +83,10 @@ export async function scheduleById( */ case "PATCH": if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.schedule .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/schedules/index.ts b/pages/api/schedules/index.ts index ac002345a3..4421844047 100644 --- a/pages/api/schedules/index.ts +++ b/pages/api/schedules/index.ts @@ -54,7 +54,10 @@ async function createOrlistAllSchedules( * description: Authorization information is missing or invalid. */ const safe = schemaScheduleBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const data = await prisma.schedule.create({ data: { ...safe.data, userId } }); const schedule = schemaSchedulePublic.parse(data); diff --git a/pages/api/selected-calendars/[id].ts b/pages/api/selected-calendars/[id].ts index 3915332412..5081da3d87 100644 --- a/pages/api/selected-calendars/[id].ts +++ b/pages/api/selected-calendars/[id].ts @@ -115,7 +115,10 @@ export async function selectedCalendarById( */ case "PATCH": if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.selectedCalendar .update({ diff --git a/pages/api/selected-calendars/index.ts b/pages/api/selected-calendars/index.ts index e7ccd9d101..f0021f9f0e 100644 --- a/pages/api/selected-calendars/index.ts +++ b/pages/api/selected-calendars/index.ts @@ -70,7 +70,10 @@ async function createOrlistAllSelectedCalendars( * description: Authorization information is missing or invalid. */ const safe = schemaSelectedCalendarBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } // Create new selectedCalendar connecting it to current userId const data = await prisma.selectedCalendar.create({ data: { ...safe.data, user: { connect: { id: userId } } }, diff --git a/pages/api/teams/[id].ts b/pages/api/teams/[id].ts index adbc5e0c12..4c8262efdc 100644 --- a/pages/api/teams/[id].ts +++ b/pages/api/teams/[id].ts @@ -102,7 +102,10 @@ export async function teamById( case "PATCH": if (!safeBody.success) { - throw new Error("Invalid request body"); + { + res.status(400).json({ message: "Invalid request body" }); + return; + } } await prisma.team .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) diff --git a/pages/api/teams/index.ts b/pages/api/teams/index.ts index 5ab45bc21d..e5f870cef6 100644 --- a/pages/api/teams/index.ts +++ b/pages/api/teams/index.ts @@ -58,7 +58,10 @@ async function createOrlistAllTeams( * description: Authorization information is missing or invalid. */ const safe = schemaTeamBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const team = await prisma.team.create({ data: safe.data }); // We're also creating the relation membership of team ownership in this call. const membership = await prisma.membership diff --git a/pages/api/users/[id].ts b/pages/api/users/[id].ts index ffaabcbf4f..b73abaf520 100644 --- a/pages/api/users/[id].ts +++ b/pages/api/users/[id].ts @@ -104,7 +104,7 @@ export async function userById( const safeBody = schemaUserEditBodyParams.safeParse(body); if (!safeBody.success) { res.status(400).json({ message: "Bad request", error: safeBody.error }); - // throw new Error("Invalid request body"); + return; } const userSchedules = await prisma.schedule.findMany({ diff --git a/templates/endpoints/get_all_and_post.ts b/templates/endpoints/get_all_and_post.ts index e21dc8bb9d..ae099c63ab 100644 --- a/templates/endpoints/get_all_and_post.ts +++ b/templates/endpoints/get_all_and_post.ts @@ -56,7 +56,10 @@ async function createOrlistAllPayments( * description: Authorization information is missing or invalid. */ const safe = schemaPaymentBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const payment = await prisma.payment.create({ data: safe.data }); const data = schemaPaymentPublic.parse(payment); diff --git a/templates/endpoints/post.ts b/templates/endpoints/post.ts index 896c09e691..35b3b013eb 100644 --- a/templates/endpoints/post.ts +++ b/templates/endpoints/post.ts @@ -31,7 +31,10 @@ import { schemaResourceBodyParams, schemaResourcePublic, withValidResource } fro */ async function createResource({body}: NextApiRequest, res: NextApiResponse) { const safe = schemaResourceBodyParams.safeParse(body); - if (!safe.success) throw new Error("Invalid request body"); + if (!safe.success) { + res.status(400).json({ message: "Invalid request body" }); + return; + } const resource = await prisma.resource.create({ data: safe.data }); const data = schemaResourcePublic.parse(resource); diff --git a/types.d.ts b/types.d.ts index 2abf07e4c1..9a7af651d1 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,2 +1 @@ declare module "modify-response-middleware"; -