diff --git a/templates/endpoints/[id]/delete.ts b/templates/endpoints/[id]/delete.ts new file mode 100644 index 0000000000..95049ae799 --- /dev/null +++ b/templates/endpoints/[id]/delete.ts @@ -0,0 +1,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"; + +/** + * @swagger + * /api/resources/{id}/delete: + * delete: + * summary: Remove an existing resource + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the resource to delete + * tags: + * - resources + * responses: + * 201: + * description: OK, resource removed successfuly + * model: Resource + * 400: + * description: Bad request. Resource id is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +export async function deleteResource(req: NextApiRequest, res: NextApiResponse) { + const safe = await schemaQueryIdParseInt.safeParse(req.query); + if (!safe.success) throw new Error("Invalid request query", safe.error); + + const data = await prisma.resource.delete({ where: { id: safe.data.id } }); + + if (data) res.status(200).json({ message: `Resource with id: ${safe.data.id} deleted successfully` }); + else + (error: Error) => + res.status(400).json({ + message: `Resource with id: ${safe.data.id} was not able to be processed`, + error, + }); +} + +export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteResource)); diff --git a/templates/endpoints/[id]/edit.ts b/templates/endpoints/[id]/edit.ts new file mode 100644 index 0000000000..e4d2f382ec --- /dev/null +++ b/templates/endpoints/[id]/edit.ts @@ -0,0 +1,56 @@ +import type { NextApiRequest, NextApiResponse } from "next"; + +import prisma from "@calcom/prisma"; + +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { ResourceResponse } from "@lib/types"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; +import { schemaResourceBodyParams, schemaResourcePublic, withValidResource } from "@lib/validations/resource"; + +/** + * @swagger + * /api/resources/{id}/edit: + * patch: + * summary: Edit an existing resource + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the resource to edit + * tags: + * - resources + * responses: + * 201: + * description: OK, resource edited successfuly + * model: Resource + * 400: + * description: Bad request. Resource body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +export async function editResource(req: NextApiRequest, res: NextApiResponse) { + const safeQuery = await schemaQueryIdParseInt.safeParse(req.query); + const safeBody = await schemaResourceBodyParams.safeParse(req.body); + + if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request"); + const resource = await prisma.resource.update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }); + const data = schemaResourcePublic.parse(resource); + + 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 withMiddleware("HTTP_PATCH")(withValidQueryIdTransformParseInt(withValidResource(editResource))); diff --git a/templates/endpoints/[id]/index.ts b/templates/endpoints/[id]/index.ts new file mode 100644 index 0000000000..0ba07d382f --- /dev/null +++ b/templates/endpoints/[id]/index.ts @@ -0,0 +1,51 @@ +import type { NextApiRequest, NextApiResponse } from "next"; + +import prisma from "@calcom/prisma"; + +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { ResourceResponse } from "@lib/types"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; +import { schemaResourcePublic } from "@lib/validations/resource"; + +/** + * @swagger + * /api/resources/{id}: + * get: + * summary: Get a resource by ID + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the resource to get + * tags: + * - resources + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: Resource was not found + */ +export async function resourceById(req: NextApiRequest, res: NextApiResponse) { + const safe = await schemaQueryIdParseInt.safeParse(req.query); + if (!safe.success) throw new Error("Invalid request query"); + + const resource = await prisma.resource.findUnique({ where: { id: safe.data.id } }); + const data = schemaResourcePublic.parse(resource); + + if (resource) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: "Resource was not found", + error, + }); +} + +export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(resourceById)); diff --git a/templates/endpoints/index.ts b/templates/endpoints/index.ts new file mode 100644 index 0000000000..4c4c98b497 --- /dev/null +++ b/templates/endpoints/index.ts @@ -0,0 +1,37 @@ +import type { NextApiRequest, NextApiResponse } from "next"; + +import prisma from "@calcom/prisma"; + +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import { ResourcesResponse } from "@lib/types"; +import { schemaResourcePublic } from "@lib/validations/resource"; + +/** + * @swagger + * /api/resources: + * get: + * summary: Get all resources + * tags: + * - resources + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: No resources were found + */ +async function allResources(_: NextApiRequest, res: NextApiResponse) { + const resources = await prisma.resource.findMany(); + const data = resources.map((resource) => schemaResourcePublic.parse(resource)); + + if (data) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: "No Resources were found", + error, + }); +} + +export default withMiddleware("HTTP_GET")(allResources); diff --git a/templates/endpoints/new.ts b/templates/endpoints/new.ts new file mode 100644 index 0000000000..bb1b0b26d2 --- /dev/null +++ b/templates/endpoints/new.ts @@ -0,0 +1,48 @@ +import type { NextApiRequest, NextApiResponse } from "next"; + +import prisma from "@calcom/prisma"; + +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { ResourceResponse } from "@lib/types"; +import { schemaResourceBodyParams, schemaResourcePublic, withValidResource } from "@lib/validations/resource"; + +/** + * @swagger + * /api/resources/new: + * post: + * summary: Creates a new resource + * requestBody: + * description: Optional description in *Markdown* + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/Resource' + * tags: + * - resources + * responses: + * 201: + * description: OK, resource created + * model: Resource + * 400: + * description: Bad request. Resource body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +async function createResource(req: NextApiRequest, res: NextApiResponse) { + const safe = schemaResourceBodyParams.safeParse(req.body); + if (!safe.success) throw new Error("Invalid request body", safe.error); + + const resource = await prisma.resource.create({ data: safe.data }); + const data = schemaResourcePublic.parse(resource); + + if (data) res.status(201).json({ data, message: "Resource created successfully" }); + else + (error: Error) => + res.status(400).json({ + message: "Could not create new resource", + error, + }); +} + +export default withMiddleware("HTTP_POST")(withValidResource(createResource)); diff --git a/templates/zod-validation.ts b/templates/zod-validation.ts new file mode 100644 index 0000000000..c200611812 --- /dev/null +++ b/templates/zod-validation.ts @@ -0,0 +1,23 @@ +// import { withValidation } from "next-validations"; +// import { z } from "zod"; + +// import { _ModelModel as Model } from "@calcom/prisma/zod"; + +// export const schemaModelBaseBodyParams = Model.omit({ id: true, userId: true, createdAt: true }).partial(); + +// const schemaModelRequiredParams = z.object({ +// email: z.string().email(), +// }); + +// export const schemaModelBodyParams = schemaModelBaseBodyParams.merge(schemaModelRequiredParams); + +// export const schemaModelPublic = Model.omit({ +// id: true, +// userId: true, +// }); + +// export const withValidModel = withValidation({ +// schema: schemaModelBodyParams, +// type: "Zod", +// mode: "body", +// });