@@ -1,27 +1,13 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _EventTypeCustomInputModel as EventTypeCustomInput } from "@calcom/prisma/zod";
|
||||
|
||||
export const schemaEventTypeCustomInputBaseBodyParams = EventTypeCustomInput.omit({
|
||||
id: true,
|
||||
eventTypeId: true,
|
||||
}).partial();
|
||||
});
|
||||
|
||||
export const schemaEventTypeCustomInputPublic = EventTypeCustomInput.omit({});
|
||||
|
||||
const schemaEventTypeCustomInputRequiredParams = z.object({
|
||||
label: z.string(),
|
||||
required: z.boolean(),
|
||||
type: z.enum(["TEXT", "TEXTLONG", "NUMBER", "BOOL"]),
|
||||
eventType: z.object({
|
||||
connect: z.object({
|
||||
id: z.number().optional(),
|
||||
}),
|
||||
// FIXME: Provide valid EventTypeModel schema here, but not sure how yet.
|
||||
create: z.any(),
|
||||
}),
|
||||
});
|
||||
export const schemaEventTypeCustomInputBodyParams = schemaEventTypeCustomInputBaseBodyParams.strict();
|
||||
|
||||
export const schemaEventTypeCustomInputBodyParams = schemaEventTypeCustomInputBaseBodyParams.merge(
|
||||
schemaEventTypeCustomInputRequiredParams
|
||||
);
|
||||
export const schemaEventTypeCustomInputEditBodyParams = schemaEventTypeCustomInputBaseBodyParams
|
||||
.partial()
|
||||
.strict();
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { EventTypeCustomInputResponse } from "@lib/types";
|
||||
import {
|
||||
schemaEventTypeCustomInputBodyParams,
|
||||
schemaEventTypeCustomInputPublic,
|
||||
} from "@lib/validations/event-type-custom-input";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs/{id}:
|
||||
* get:
|
||||
* summary: Find a eventTypeCustomInput
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: ID of the eventTypeCustomInput to get
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: EventType was not found
|
||||
* patch:
|
||||
* summary: Edit an existing eventTypeCustomInput
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: ID of the eventTypeCustomInput to edit
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. EventType body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing eventTypeCustomInput
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: ID of the eventTypeCustomInput to delete
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. EventType id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function eventTypeById(
|
||||
{ method, query, body, userId, prisma }: NextApiRequest,
|
||||
res: NextApiResponse<EventTypeCustomInputResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaEventTypeCustomInputBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) {
|
||||
res.status(400).json({ message: "Your query was invalid" });
|
||||
return;
|
||||
}
|
||||
const data = await prisma.eventType.findMany({ where: { userId } });
|
||||
const userEventTypes = data.map((eventType) => eventType.id);
|
||||
const userEventTypeCustomInputs = await prisma.eventTypeCustomInput.findMany({
|
||||
where: { eventType: userEventTypes },
|
||||
});
|
||||
const userEventTypeCustomInputIds = userEventTypeCustomInputs.map(
|
||||
(eventTypeCustomInput) => eventTypeCustomInput.id
|
||||
);
|
||||
if (!userEventTypeCustomInputIds.includes(safeQuery.data.id))
|
||||
res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
case "GET":
|
||||
await prisma.eventTypeCustomInput
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
.then((data) => schemaEventTypeCustomInputPublic.parse(data))
|
||||
.then((event_type_custom_input) => res.status(200).json({ event_type_custom_input }))
|
||||
.catch((error: Error) =>
|
||||
res.status(404).json({
|
||||
message: `EventType with id: ${safeQuery.data.id} not found`,
|
||||
error,
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
case "PATCH":
|
||||
if (!safeBody.success) {
|
||||
{
|
||||
res.status(400).json({ message: "Invalid request body" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
await prisma.eventTypeCustomInput
|
||||
.update({ where: { id: safeQuery.data.id }, data: safeBody.data })
|
||||
.then((data) => schemaEventTypeCustomInputPublic.parse(data))
|
||||
.then((event_type_custom_input) => res.status(200).json({ event_type_custom_input }))
|
||||
.catch((error: Error) =>
|
||||
res.status(404).json({
|
||||
message: `EventType with id: ${safeQuery.data.id} not found`,
|
||||
error,
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
case "DELETE":
|
||||
await prisma.eventTypeCustomInput
|
||||
.delete({
|
||||
where: { id: safeQuery.data.id },
|
||||
})
|
||||
.then(() =>
|
||||
res.status(200).json({
|
||||
message: `CustomInputEventType with id: ${safeQuery.data.id} deleted`,
|
||||
})
|
||||
)
|
||||
.catch((error: Error) =>
|
||||
res.status(404).json({
|
||||
message: `EventType with id: ${safeQuery.data.id} not found`,
|
||||
error,
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
res.status(405).json({ message: "Method not allowed" });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_GET_DELETE_PATCH")(withValidQueryIdTransformParseInt(eventTypeById));
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { NextApiRequest } from "next";
|
||||
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
|
||||
import { schemaQueryIdParseInt } from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
async function authMiddleware(req: NextApiRequest) {
|
||||
const { userId, isAdmin, prisma } = req;
|
||||
const { id } = schemaQueryIdParseInt.parse(req.query);
|
||||
// Admins can just skip this check
|
||||
if (isAdmin) return;
|
||||
// Check if the current user can access the event type of this input
|
||||
const eventTypeCustomInput = await prisma.eventTypeCustomInput.findFirst({
|
||||
where: { id, eventType: { userId } },
|
||||
});
|
||||
if (!eventTypeCustomInput) throw new HttpError({ statusCode: 401, message: "Unauthorized" });
|
||||
}
|
||||
|
||||
export default authMiddleware;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { NextApiRequest } from "next";
|
||||
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
import { schemaQueryIdParseInt } from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs/{id}:
|
||||
* delete:
|
||||
* summary: Remove an existing eventTypeCustomInput
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: ID of the eventTypeCustomInput to delete
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput removed successfully
|
||||
* 400:
|
||||
* description: Bad request. EventType id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function deleteHandler(req: NextApiRequest) {
|
||||
const { prisma, query } = req;
|
||||
const { id } = schemaQueryIdParseInt.parse(query);
|
||||
await prisma.eventTypeCustomInput.delete({ where: { id } });
|
||||
return { message: `CustomInputEventType with id: ${id} deleted successfully` };
|
||||
}
|
||||
|
||||
export default defaultResponder(deleteHandler);
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { NextApiRequest } from "next";
|
||||
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
import { schemaEventTypeCustomInputPublic } from "@lib/validations/event-type-custom-input";
|
||||
import { schemaQueryIdParseInt } from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs/{id}:
|
||||
* get:
|
||||
* summary: Find a eventTypeCustomInput
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: ID of the eventTypeCustomInput to get
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: EventType was not found
|
||||
*/
|
||||
export async function getHandler(req: NextApiRequest) {
|
||||
const { prisma, query } = req;
|
||||
const { id } = schemaQueryIdParseInt.parse(query);
|
||||
const data = await prisma.eventTypeCustomInput.findUniqueOrThrow({ where: { id } });
|
||||
return { event_type_custom_input: schemaEventTypeCustomInputPublic.parse(data) };
|
||||
}
|
||||
|
||||
export default defaultResponder(getHandler);
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { NextApiRequest } from "next";
|
||||
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
import {
|
||||
schemaEventTypeCustomInputEditBodyParams,
|
||||
schemaEventTypeCustomInputPublic,
|
||||
} from "@lib/validations/event-type-custom-input";
|
||||
import { schemaQueryIdParseInt } from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing eventTypeCustomInput
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: ID of the eventTypeCustomInput to edit
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput edited successfully
|
||||
* 400:
|
||||
* description: Bad request. EventType body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function patchHandler(req: NextApiRequest) {
|
||||
const { prisma, query } = req;
|
||||
const { id } = schemaQueryIdParseInt.parse(query);
|
||||
const data = schemaEventTypeCustomInputEditBodyParams.parse(req.body);
|
||||
const result = await prisma.eventTypeCustomInput.update({ where: { id }, data });
|
||||
return { event_type_custom_input: schemaEventTypeCustomInputPublic.parse(result) };
|
||||
}
|
||||
|
||||
export default defaultResponder(patchHandler);
|
||||
@@ -0,0 +1,18 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { defaultHandler, defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
|
||||
import authMiddleware from "./_auth-middleware";
|
||||
|
||||
export default withMiddleware("HTTP_GET_DELETE_PATCH")(
|
||||
defaultResponder(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
await authMiddleware(req);
|
||||
return defaultHandler({
|
||||
GET: import("./_get"),
|
||||
PATCH: import("./_patch"),
|
||||
DELETE: import("./_delete"),
|
||||
})(req, res);
|
||||
})
|
||||
);
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import type { NextApiRequest } from "next";
|
||||
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
import { schemaEventTypeCustomInputPublic } from "@lib/validations/event-type-custom-input";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs:
|
||||
* get:
|
||||
* summary: Find all eventTypeCustomInputs
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No eventTypeCustomInputs were found
|
||||
*/
|
||||
async function getHandler(req: NextApiRequest) {
|
||||
const { userId, isAdmin, prisma } = req;
|
||||
const args: Prisma.EventTypeCustomInputFindManyArgs = isAdmin ? {} : { where: { eventType: { userId } } };
|
||||
const data = await prisma.eventTypeCustomInput.findMany(args);
|
||||
return { event_type_custom_inputs: data.map((v) => schemaEventTypeCustomInputPublic.parse(v)) };
|
||||
}
|
||||
|
||||
export default defaultResponder(getHandler);
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { NextApiRequest } from "next";
|
||||
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
import {
|
||||
schemaEventTypeCustomInputBodyParams,
|
||||
schemaEventTypeCustomInputPublic,
|
||||
} from "@lib/validations/event-type-custom-input";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs:
|
||||
* post:
|
||||
* summary: Creates a new eventTypeCustomInput
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput created
|
||||
* 400:
|
||||
* description: Bad request. EventTypeCustomInput body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function postHandler(req: NextApiRequest) {
|
||||
const { userId, isAdmin, prisma } = req;
|
||||
const { eventTypeId, ...body } = schemaEventTypeCustomInputBodyParams.parse(req.body);
|
||||
|
||||
if (!isAdmin) {
|
||||
/* We check that the user has access to the event type he's trying to add a custom input to. */
|
||||
const eventType = await prisma.eventType.findFirst({
|
||||
where: { id: eventTypeId, userId },
|
||||
});
|
||||
if (!eventType) throw new HttpError({ statusCode: 401, message: "Unauthorized" });
|
||||
}
|
||||
|
||||
const data = await prisma.eventTypeCustomInput.create({
|
||||
data: { ...body, eventType: { connect: { id: eventTypeId } } },
|
||||
});
|
||||
|
||||
return {
|
||||
event_type_custom_input: schemaEventTypeCustomInputPublic.parse(data),
|
||||
message: "EventTypeCustomInput created successfully",
|
||||
};
|
||||
}
|
||||
|
||||
export default defaultResponder(postHandler);
|
||||
@@ -1,91 +1,10 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { defaultHandler } from "@calcom/lib/server";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { EventTypeCustomInputResponse, EventTypeCustomInputsResponse } from "@lib/types";
|
||||
import {
|
||||
schemaEventTypeCustomInputBodyParams,
|
||||
schemaEventTypeCustomInputPublic,
|
||||
} from "@lib/validations/event-type-custom-input";
|
||||
|
||||
async function createOrlistAllEventTypeCustomInputs(
|
||||
{ userId, method, body, prisma }: NextApiRequest,
|
||||
res: NextApiResponse<EventTypeCustomInputsResponse | EventTypeCustomInputResponse>
|
||||
) {
|
||||
const data = await prisma.eventType.findMany({ where: { userId } });
|
||||
const userEventTypes: number[] = data.map((eventType) => eventType.id);
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs:
|
||||
* get:
|
||||
* summary: Find all eventTypeCustomInputs
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No eventTypeCustomInputs were found
|
||||
*/
|
||||
const data = await prisma.eventTypeCustomInput.findMany({ where: { eventType: userEventTypes } });
|
||||
const event_type_custom_inputs = data.map((eventTypeCustomInput) =>
|
||||
schemaEventTypeCustomInputPublic.parse(eventTypeCustomInput)
|
||||
);
|
||||
if (event_type_custom_inputs) res.status(200).json({ event_type_custom_inputs });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(404).json({
|
||||
message: "No EventTypeCustomInputs were found",
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs:
|
||||
* post:
|
||||
* summary: Creates a new eventTypeCustomInput
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput created
|
||||
* 400:
|
||||
* description: Bad request. EventTypeCustomInput body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaEventTypeCustomInputBodyParams.safeParse(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)) {
|
||||
const data = await prisma.eventTypeCustomInput.create({ data: { ...safe.data } });
|
||||
const event_type_custom_input = schemaEventTypeCustomInputPublic.parse(data);
|
||||
if (event_type_custom_input)
|
||||
res
|
||||
.status(201)
|
||||
.json({ event_type_custom_input, message: "EventTypeCustomInput created successfully" });
|
||||
// When creating, no need
|
||||
// FIXME: we might want to pass userId to the new created/linked eventType, though.
|
||||
} else if (safe.data.eventType.create) {
|
||||
const data = await prisma.eventTypeCustomInput.create({ data: { ...safe.data } });
|
||||
const event_type_custom_input = schemaEventTypeCustomInputPublic.parse(data);
|
||||
if (event_type_custom_input)
|
||||
res
|
||||
.status(201)
|
||||
.json({ event_type_custom_input, message: "EventTypeCustomInput created successfully" });
|
||||
} else
|
||||
(error: Error) =>
|
||||
res.status(400).json({
|
||||
message: "Could not create new eventTypeCustomInput",
|
||||
error,
|
||||
});
|
||||
} else res.status(405).json({ message: `Method ${method} not allowed` });
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_GET_OR_POST")(createOrlistAllEventTypeCustomInputs);
|
||||
export default withMiddleware("HTTP_GET_OR_POST")(
|
||||
defaultHandler({
|
||||
GET: import("./_get"),
|
||||
POST: import("./_post"),
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user