chore: bring up to date booking references, bookings, and credentials

This commit is contained in:
Agusti Fernandez Pardo
2022-04-01 23:03:03 +02:00
parent 55f93cded6
commit 1c19032884
20 changed files with 593 additions and 258 deletions
+1
View File
@@ -2,6 +2,7 @@ import {
User,
ApiKey,
Team,
Credential,
SelectedCalendar,
EventType,
Attendee,
+11 -1
View File
@@ -1,11 +1,21 @@
import { withValidation } from "next-validations";
import { z } from "zod";
import { _BookingReferenceModel as BookingReference } from "@calcom/prisma/zod";
export const schemaBookingReferenceBodyParams = BookingReference.omit({ id: true });
export const schemaBookingReferenceBaseBodyParams = BookingReference.omit({ id: true }).partial();
export const schemaBookingReferencePublic = BookingReference.omit({});
const schemaBookingReferenceRequiredParams = z.object({
type: z.string(),
uid: z.string(),
});
export const schemaBookingReferenceBodyParams = schemaBookingReferenceBaseBodyParams.merge(
schemaBookingReferenceRequiredParams
);
export const withValidBookingReference = withValidation({
schema: schemaBookingReferenceBodyParams,
type: "Zod",
+1 -3
View File
@@ -3,10 +3,8 @@ import { z } from "zod";
import { _BookingModel as Booking } from "@calcom/prisma/zod";
// Here we remove any parameters that are not needed for the API with omit.
const schemaBookingBaseBodyParams = Booking.omit({ id: true }).partial();
// Here we redeclare the required ones after removing the ones we don't need.
// and making the rest optional with .partial()
const schemaBookingRequiredParams = z.object({
uid: z.string(),
title: z.string(),
+13 -1
View File
@@ -1,8 +1,20 @@
import { withValidation } from "next-validations";
import { z } from "zod";
import { _CredentialModel as Credential } from "@calcom/prisma/zod";
export const schemaCredentialBodyParams = Credential.omit({ id: true });
import { jsonSchema } from "./shared/jsonSchema";
const schemaCredentialBaseBodyParams = Credential.omit({ id: true, userId: true }).partial();
const schemaCredentialRequiredParams = z.object({
type: z.string(),
key: jsonSchema,
});
export const schemaCredentialBodyParams = schemaCredentialBaseBodyParams.merge(
schemaCredentialRequiredParams
);
export const schemaCredentialPublic = Credential.omit({});
+9
View File
@@ -0,0 +1,9 @@
import { z } from "zod";
// Helper schema for JSON fields
type Literal = boolean | number | string;
type Json = Literal | { [key: string]: Json } | Json[];
const literalSchema = z.union([z.string(), z.number(), z.boolean()]);
export const jsonSchema: z.ZodSchema<Json> = z.lazy(() =>
z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])
);
+39 -17
View File
@@ -2,28 +2,50 @@ import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BaseResponse } from "@lib/types";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/booking-references/{id}/delete:
* delete:
* summary: Remove an existing bookingReference
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the bookingReference to delete
* tags:
* - bookingReferences
* responses:
* 201:
* description: OK, bookingReference removed successfuly
* model: BookingReference
* 400:
* description: Bad request. BookingReference id is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function deleteBookingReference(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query", safe.error);
export async function deleteBookingReference(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "DELETE" && safe.success && safe.data) {
const bookingReference = await prisma.bookingReference.delete({ where: { id: safe.data.id } });
// We only remove the bookingReference type from the database if there's an existing resource.
if (bookingReference)
res.status(200).json({ message: `bookingReference with id: ${safe.data.id} deleted successfully` });
// This catches the error thrown by prisma.bookingReference.delete() if the resource is not found.
else res.status(400).json({ message: `Resource with id:${safe.data.id} was not found` });
// Reject any other HTTP method than POST
} else res.status(405).json({ message: "Only DELETE Method allowed" });
const data = await prisma.bookingReference.delete({ where: { id: safe.data.id } });
if (data)
res.status(200).json({ message: `BookingReference with id: ${safe.data.id} deleted successfully` });
else
(error: Error) =>
res.status(400).json({
message: `BookingReference with id: ${safe.data.id} was not able to be processed`,
error,
});
}
export default withValidQueryIdTransformParseInt(deleteBookingReference);
export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteBookingReference));
+52 -25
View File
@@ -1,38 +1,65 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { BookingReference } from "@calcom/prisma/client";
import { schemaBookingReference, withValidBookingReference } from "@lib/validations/booking-reference";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BookingReferenceResponse } from "@lib/types";
import {
schemaBookingReferenceBodyParams,
schemaBookingReferencePublic,
withValidBookingReference,
} from "@lib/validations/booking-reference";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: BookingReference;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/booking-references/{id}/edit:
* patch:
* summary: Edit an existing bookingReference
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the bookingReference to edit
* tags:
* - bookingReferences
* responses:
* 201:
* description: OK, bookingReference edited successfuly
* model: BookingReference
* 400:
* description: Bad request. BookingReference body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function editBookingReference(
req: NextApiRequest,
res: NextApiResponse<BookingReferenceResponse>
) {
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
const safeBody = await schemaBookingReferenceBodyParams.safeParse(req.body);
export async function editBookingReference(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, body, method } = req;
const safeQuery = await schemaQueryIdParseInt.safeParse(query);
const safeBody = await schemaBookingReference.safeParse(body);
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
const bookingReference = await prisma.bookingReference.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
});
const data = schemaBookingReferencePublic.parse(bookingReference);
if (method === "PATCH" && safeQuery.success && safeBody.success) {
const data = await prisma.bookingReference.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
});
if (data) res.status(200).json({ data });
else
res
.status(404)
.json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated` });
// Reject any other HTTP method than POST
} else res.status(405).json({ message: "Only PATCH Method allowed for updating bookingReferences" });
if (data) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`,
error,
});
}
export default withValidQueryIdTransformParseInt(withValidBookingReference(editBookingReference));
export default withMiddleware("HTTP_PATCH")(
withValidQueryIdTransformParseInt(withValidBookingReference(editBookingReference))
);
+41 -16
View File
@@ -1,29 +1,54 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { BookingReference } from "@calcom/prisma/client";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BookingReferenceResponse } from "@lib/types";
import { schemaBookingReferencePublic } from "@lib/validations/booking-reference";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: BookingReference;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/booking-references/{id}:
* get:
* summary: Get a bookingReference by ID
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the bookingReference to get
* tags:
* - bookingReferences
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: BookingReference was not found
*/
export async function bookingReferenceById(
req: NextApiRequest,
res: NextApiResponse<BookingReferenceResponse>
) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query");
export async function bookingReference(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "GET" && safe.success) {
const data = await prisma.bookingReference.findUnique({ where: { id: safe.data.id } });
const bookingReference = await prisma.bookingReference.findUnique({ where: { id: safe.data.id } });
const data = schemaBookingReferencePublic.parse(bookingReference);
if (data) res.status(200).json({ data });
else res.status(404).json({ message: "Event type not found" });
// Reject any other HTTP method than POST
} else res.status(405).json({ message: "Only GET Method allowed" });
if (bookingReference) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "BookingReference was not found",
error,
});
}
export default withValidQueryIdTransformParseInt(bookingReference);
export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(bookingReferenceById));
+32 -8
View File
@@ -1,15 +1,39 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { BookingReference } from "@calcom/prisma/client";
type ResponseData = {
data?: BookingReference[];
error?: unknown;
};
import { withMiddleware } from "@lib/helpers/withMiddleware";
import { BookingReferencesResponse } from "@lib/types";
import { schemaBookingReferencePublic } from "@lib/validations/booking-reference";
/**
* @swagger
* /api/booking-references:
* get:
* summary: Get all bookingReferences
* tags:
* - bookingReferences
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: No bookingReferences were found
*/
async function allBookingReferences(_: NextApiRequest, res: NextApiResponse<BookingReferencesResponse>) {
const bookingReferences = await prisma.bookingReference.findMany();
const data = bookingReferences.map((bookingReference) =>
schemaBookingReferencePublic.parse(bookingReference)
);
export default async function bookingReference(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const data = await prisma.bookingReference.findMany();
if (data) res.status(200).json({ data });
else res.status(400).json({ error: "No data found" });
else
(error: Error) =>
res.status(404).json({
message: "No BookingReferences were found",
error,
});
}
export default withMiddleware("HTTP_GET")(allBookingReferences);
+44 -20
View File
@@ -1,28 +1,52 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { BookingReference } from "@calcom/prisma/client";
import { schemaBookingReference, withValidBookingReference } from "@lib/validations/booking-reference";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BookingReferenceResponse } from "@lib/types";
import {
schemaBookingReferenceBodyParams,
schemaBookingReferencePublic,
withValidBookingReference,
} from "@lib/validations/booking-reference";
type ResponseData = {
data?: BookingReference;
message?: string;
error?: string;
};
/**
* @swagger
* /api/booking-references/new:
* post:
* summary: Creates a new bookingReference
* requestBody:
* description: Optional description in *Markdown*
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/BookingReference'
* tags:
* - bookingReferences
* responses:
* 201:
* description: OK, bookingReference created
* model: BookingReference
* 400:
* description: Bad request. BookingReference body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
async function createBookingReference(req: NextApiRequest, res: NextApiResponse<BookingReferenceResponse>) {
const safe = schemaBookingReferenceBodyParams.safeParse(req.body);
if (!safe.success) throw new Error("Invalid request body", safe.error);
async function createBookingReference(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { body, method } = req;
const safe = schemaBookingReference.safeParse(body);
if (method === "POST" && safe.success) {
await prisma.bookingReference
.create({ data: safe.data })
.then((data) => res.status(201).json({ data }))
.catch((error) =>
res.status(400).json({ message: "Could not create bookingReference type", error: error })
);
// Reject any other HTTP method than POST
} else res.status(405).json({ error: "Only POST Method allowed" });
const bookingReference = await prisma.bookingReference.create({ data: safe.data });
const data = schemaBookingReferencePublic.parse(bookingReference);
if (data) res.status(201).json({ data, message: "BookingReference created successfully" });
else
(error: Error) =>
res.status(400).json({
message: "Could not create new bookingReference",
error,
});
}
export default withValidBookingReference(createBookingReference);
export default withMiddleware("HTTP_POST")(withValidBookingReference(createBookingReference));
+38 -17
View File
@@ -2,28 +2,49 @@ import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BaseResponse } from "@lib/types";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/bookings/{id}/delete:
* delete:
* summary: Remove an existing booking
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the booking to delete
* tags:
* - bookings
* responses:
* 201:
* description: OK, booking removed successfuly
* model: Booking
* 400:
* description: Bad request. Booking id is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function deleteBooking(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query", safe.error);
export async function deleteBooking(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "DELETE" && safe.success && safe.data) {
const booking = await prisma.booking.delete({ where: { id: safe.data.id } });
// We only remove the booking type from the database if there's an existing resource.
if (booking) res.status(200).json({ message: `booking with id: ${safe.data.id} deleted successfully` });
// This catches the error thrown by prisma.booking.delete() if the resource is not found.
else res.status(400).json({ message: `Resource with id:${safe.data.id} was not found` });
// Reject any other HTTP method than POST
} else
res.status(405).json({ message: "Only DELETE Method allowed in /availabilities/[id]/delete endpoint" });
const data = await prisma.booking.delete({ where: { id: safe.data.id } });
if (data) res.status(200).json({ message: `Booking with id: ${safe.data.id} deleted successfully` });
else
(error: Error) =>
res.status(400).json({
message: `Booking with id: ${safe.data.id} was not able to be processed`,
error,
});
}
export default withValidQueryIdTransformParseInt(deleteBooking);
export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteBooking));
+43 -32
View File
@@ -1,45 +1,56 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Booking } from "@calcom/prisma/client";
import { schemaBooking, withValidBooking } from "@lib/validations/booking";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BookingResponse } from "@lib/types";
import { schemaBookingBodyParams, schemaBookingPublic, withValidBooking } from "@lib/validations/booking";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Booking;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/bookings/{id}/edit:
* patch:
* summary: Edit an existing booking
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the booking to edit
* tags:
* - bookings
* responses:
* 201:
* description: OK, booking edited successfuly
* model: Booking
* 400:
* description: Bad request. Booking body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function editBooking(req: NextApiRequest, res: NextApiResponse<BookingResponse>) {
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
const safeBody = await schemaBookingBodyParams.safeParse(req.body);
export async function editBooking(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, body, method } = req;
const safeQuery = await schemaQueryIdParseInt.safeParse(query);
const safeBody = await schemaBooking.safeParse(body);
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
const booking = await prisma.booking.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
});
const data = schemaBookingPublic.parse(booking);
if (method === "PATCH") {
if (safeQuery.success && safeBody.success) {
await prisma.booking
.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
})
.then((booking) => {
res.status(200).json({ data: booking });
})
.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 bookings" });
}
if (data) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`,
error,
});
}
export default withValidQueryIdTransformParseInt(withValidBooking(editBooking));
export default withMiddleware("HTTP_PATCH")(withValidQueryIdTransformParseInt(withValidBooking(editBooking)));
+38 -19
View File
@@ -1,32 +1,51 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Booking } from "@calcom/prisma/client";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BookingResponse } from "@lib/types";
import { schemaBookingPublic } from "@lib/validations/booking";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Booking;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/bookings/{id}:
* get:
* summary: Get a booking by ID
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the booking to get
* tags:
* - bookings
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: Booking was not found
*/
export async function bookingById(req: NextApiRequest, res: NextApiResponse<BookingResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query");
export async function booking(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
const booking = await prisma.booking.findUnique({ where: { id: safe.data.id } });
const data = schemaBookingPublic.parse(booking);
if (method === "GET" && safe.success) {
const booking = await prisma.booking.findUnique({ where: { id: safe.data.id } });
if (booking) res.status(200).json({ data: booking });
if (!booking) 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" });
}
if (booking) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "Booking was not found",
error,
});
}
export default withValidQueryIdTransformParseInt(booking);
export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(bookingById));
+31 -13
View File
@@ -1,19 +1,37 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Booking } from "@calcom/prisma/client";
type ResponseData = {
data?: Booking[];
error?: unknown;
};
import { withMiddleware } from "@lib/helpers/withMiddleware";
import { BookingsResponse } from "@lib/types";
import { schemaBookingPublic } from "@lib/validations/booking";
export default async function booking(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
try {
const data = await prisma.booking.findMany();
res.status(200).json({ data });
} catch (error) {
// FIXME: Add zod for validation/error handling
res.status(400).json({ error: error });
}
/**
* @swagger
* /api/bookings:
* get:
* summary: Get all bookings
* tags:
* - bookings
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: No bookings were found
*/
async function allBookings(_: NextApiRequest, res: NextApiResponse<BookingsResponse>) {
const bookings = await prisma.booking.findMany();
const data = bookings.map((booking) => schemaBookingPublic.parse(booking));
if (data) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "No Bookings were found",
error,
});
}
export default withMiddleware("HTTP_GET")(allBookings);
+1 -2
View File
@@ -2,7 +2,6 @@ import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { withCost } from "@lib/helpers/withCost";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BookingResponse } from "@lib/types";
import { schemaBookingBodyParams, schemaBookingPublic, withValidBooking } from "@lib/validations/booking";
@@ -46,4 +45,4 @@ async function createBooking(req: NextApiRequest, res: NextApiResponse<BookingRe
});
}
export default withMiddleware(withCost(5), "HTTP_POST")(withValidBooking(createBooking));
export default withMiddleware("HTTP_POST")(withValidBooking(createBooking));
+38 -17
View File
@@ -2,28 +2,49 @@ import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BaseResponse } from "@lib/types";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/credentials/{id}/delete:
* delete:
* summary: Remove an existing credential
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the credential to delete
* tags:
* - credentials
* responses:
* 201:
* description: OK, credential removed successfuly
* model: Credential
* 400:
* description: Bad request. Credential id is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function deleteCredential(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query", safe.error);
export async function deleteCredential(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "DELETE" && safe.success && safe.data) {
const credential = await prisma.credential.delete({ where: { id: safe.data.id } });
// We only remove the credential type from the database if there's an existing resource.
if (credential)
res.status(200).json({ message: `credential with id: ${safe.data.id} deleted successfully` });
// This catches the error thrown by prisma.credential.delete() if the resource is not found.
else res.status(400).json({ message: `Resource with id:${safe.data.id} was not found` });
// Reject any other HTTP method than POST
} else res.status(405).json({ message: "Only DELETE Method allowed" });
const data = await prisma.credential.delete({ where: { id: safe.data.id } });
if (data) res.status(200).json({ message: `Credential with id: ${safe.data.id} deleted successfully` });
else
(error: Error) =>
res.status(400).json({
message: `Credential with id: ${safe.data.id} was not able to be processed`,
error,
});
}
export default withValidQueryIdTransformParseInt(deleteCredential);
export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteCredential));
+49 -25
View File
@@ -1,38 +1,62 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Credential } from "@calcom/prisma/client";
import { schemaCredential, withValidCredential } from "@lib/validations/credential";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { CredentialResponse } from "@lib/types";
import {
schemaCredentialBodyParams,
schemaCredentialPublic,
withValidCredential,
} from "@lib/validations/credential";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Credential;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/credentials/{id}/edit:
* patch:
* summary: Edit an existing credential
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the credential to edit
* tags:
* - credentials
* responses:
* 201:
* description: OK, credential edited successfuly
* model: Credential
* 400:
* description: Bad request. Credential body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function editCredential(req: NextApiRequest, res: NextApiResponse<CredentialResponse>) {
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
const safeBody = await schemaCredentialBodyParams.safeParse(req.body);
export async function editCredential(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, body, method } = req;
const safeQuery = await schemaQueryIdParseInt.safeParse(query);
const safeBody = await schemaCredential.safeParse(body);
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
const credential = await prisma.credential.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
});
const data = schemaCredentialPublic.parse(credential);
if (method === "PATCH" && safeQuery.success && safeBody.success) {
const data = await prisma.credential.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
});
if (data) res.status(200).json({ data });
else
res
.status(404)
.json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error });
// Reject any other HTTP method than POST
} else res.status(405).json({ message: "Only PATCH Method allowed for updating credentials" });
if (data) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`,
error,
});
}
export default withValidQueryIdTransformParseInt(withValidCredential(editCredential));
export default withMiddleware("HTTP_PATCH")(
withValidQueryIdTransformParseInt(withValidCredential(editCredential))
);
+38 -16
View File
@@ -1,29 +1,51 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Credential } from "@calcom/prisma/client";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { CredentialResponse } from "@lib/types";
import { schemaCredentialPublic } from "@lib/validations/credential";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Credential;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/credentials/{id}:
* get:
* summary: Get a credential by ID
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the credential to get
* tags:
* - credentials
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: Credential was not found
*/
export async function credentialById(req: NextApiRequest, res: NextApiResponse<CredentialResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query");
export async function credential(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "GET" && safe.success) {
const data = await prisma.credential.findUnique({ where: { id: safe.data.id } });
const credential = await prisma.credential.findUnique({ where: { id: safe.data.id } });
const data = schemaCredentialPublic.parse(credential);
if (data) res.status(200).json({ data });
else res.status(404).json({ message: "Event type not found" });
// Reject any other HTTP method than POST
} else res.status(405).json({ message: "Only GET Method allowed" });
if (credential) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "Credential was not found",
error,
});
}
export default withValidQueryIdTransformParseInt(credential);
export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(credentialById));
+30 -8
View File
@@ -1,15 +1,37 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Credential } from "@calcom/prisma/client";
type ResponseData = {
data?: Credential[];
error?: unknown;
};
import { withMiddleware } from "@lib/helpers/withMiddleware";
import { CredentialsResponse } from "@lib/types";
import { schemaCredentialPublic } from "@lib/validations/credential";
/**
* @swagger
* /api/credentials:
* get:
* summary: Get all credentials
* tags:
* - credentials
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: No credentials were found
*/
async function allCredentials(_: NextApiRequest, res: NextApiResponse<CredentialsResponse>) {
const credentials = await prisma.credential.findMany();
const data = credentials.map((credential) => schemaCredentialPublic.parse(credential));
export default async function credential(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const data = await prisma.credential.findMany();
if (data) res.status(200).json({ data });
else res.status(400).json({ error: "No data found" });
else
(error: Error) =>
res.status(404).json({
message: "No Credentials were found",
error,
});
}
export default withMiddleware("HTTP_GET")(allCredentials);
+44 -18
View File
@@ -1,26 +1,52 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Credential } from "@calcom/prisma/client";
import { schemaCredential, withValidCredential } from "@lib/validations/credential";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { CredentialResponse } from "@lib/types";
import {
schemaCredentialBodyParams,
schemaCredentialPublic,
withValidCredential,
} from "@lib/validations/credential";
type ResponseData = {
data?: Credential;
message?: string;
error?: string;
};
/**
* @swagger
* /api/credentials/new:
* post:
* summary: Creates a new credential
* requestBody:
* description: Optional description in *Markdown*
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Credential'
* tags:
* - credentials
* responses:
* 201:
* description: OK, credential created
* model: Credential
* 400:
* description: Bad request. Credential body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
async function createCredential(req: NextApiRequest, res: NextApiResponse<CredentialResponse>) {
const safe = schemaCredentialBodyParams.safeParse(req.body);
if (!safe.success) throw new Error("Invalid request body", safe.error);
async function createCredential(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { body, method } = req;
const safe = schemaCredential.safeParse(body);
if (method === "POST" && safe.success) {
await prisma.credential
.create({ data: safe.data })
.then((data) => res.status(201).json({ data }))
.catch((error) => res.status(400).json({ message: "Could not create credential type", error: error }));
// Reject any other HTTP method than POST
} else res.status(405).json({ error: "Only POST Method allowed" });
const credential = await prisma.credential.create({ data: safe.data });
const data = schemaCredentialPublic.parse(credential);
if (data) res.status(201).json({ data, message: "Credential created successfully" });
else
(error: Error) =>
res.status(400).json({
message: "Could not create new credential",
error,
});
}
export default withValidCredential(createCredential);
export default withMiddleware("HTTP_POST")(withValidCredential(createCredential));