From 1de7bc4146a770068709d3524c636d7afffe592d Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Wed, 30 Mar 2022 14:17:55 +0200 Subject: [PATCH] prettier --- .eslintrc.json | 28 ++++--- .prettierignore | 3 + README.md | 6 +- jest.config.ts | 30 +------ lib/helpers/addRequestid.ts | 12 +-- lib/helpers/captureErrors.ts | 6 +- lib/helpers/httpMethods.ts | 14 ++-- lib/helpers/verifyApiKey.ts | 25 +++--- lib/helpers/withMiddleware.ts | 19 +++-- lib/types.ts | 22 +++++ lib/utils/stringifyISODate.ts | 8 +- lib/validations/apiKey.ts | 25 +++--- lib/validations/availability.ts | 4 +- lib/validations/booking-reference.ts | 4 +- lib/validations/booking.ts | 2 +- lib/validations/credential.ts | 4 +- lib/validations/daily-event-reference.ts | 4 +- lib/validations/destination-calendar.ts | 4 +- lib/validations/eventType.ts | 2 +- lib/validations/membership.ts | 4 +- lib/validations/payment.ts | 4 +- lib/validations/schedule.ts | 4 +- lib/validations/selected-calendar.ts | 4 +- lib/validations/shared/baseApiParams.ts | 13 +++ lib/validations/shared/queryIdString.ts | 17 ++-- .../shared/queryIdTransformParseInt.ts | 15 ++-- lib/validations/team.ts | 2 +- lib/validations/user.ts | 80 ++++++------------- lib/validations/webhook.ts | 4 +- next.config.js | 4 +- package.json | 2 +- pages/_middleware.ts | 3 +- pages/api/api-keys/[id]/delete.ts | 11 +-- pages/api/api-keys/[id]/edit.ts | 36 +++++---- pages/api/api-keys/[id]/index.ts | 18 ++--- pages/api/api-keys/index.ts | 11 +-- pages/api/api-keys/new.ts | 22 +++-- pages/api/attendees/[id]/delete.ts | 13 +-- pages/api/attendees/[id]/edit.ts | 34 +++++--- pages/api/attendees/[id]/index.ts | 13 +-- pages/api/attendees/index.ts | 6 +- pages/api/attendees/new.ts | 18 ++--- pages/api/availabilities/[id]/delete.ts | 13 +-- pages/api/availabilities/[id]/edit.ts | 30 ++++--- pages/api/availabilities/[id]/index.ts | 14 ++-- pages/api/availabilities/index.ts | 6 +- pages/api/availabilities/new.ts | 10 ++- pages/api/booking-references/[id]/delete.ts | 16 ++-- pages/api/booking-references/[id]/edit.ts | 26 +++--- pages/api/booking-references/[id]/index.ts | 12 +-- pages/api/booking-references/index.ts | 6 +- pages/api/booking-references/new.ts | 18 +++-- pages/api/bookings/[id]/delete.ts | 16 ++-- pages/api/bookings/[id]/edit.ts | 34 +++++--- pages/api/bookings/[id]/index.ts | 12 +-- pages/api/bookings/index.ts | 6 +- pages/api/bookings/new.ts | 6 +- pages/api/credentials/[id]/delete.ts | 16 ++-- pages/api/credentials/[id]/edit.ts | 26 +++--- pages/api/credentials/[id]/index.ts | 12 +-- pages/api/credentials/index.ts | 6 +- pages/api/credentials/new.ts | 16 ++-- .../api/daily-event-references/[id]/delete.ts | 26 +++--- pages/api/daily-event-references/[id]/edit.ts | 31 ++++--- .../api/daily-event-references/[id]/index.ts | 12 +-- pages/api/daily-event-references/index.ts | 6 +- pages/api/daily-event-references/new.ts | 23 +++--- .../api/destination-calendars/[id]/delete.ts | 16 ++-- pages/api/destination-calendars/[id]/edit.ts | 31 ++++--- pages/api/destination-calendars/[id]/index.ts | 12 +-- pages/api/destination-calendars/index.ts | 6 +- pages/api/destination-calendars/new.ts | 23 +++--- .../event-type-custom-inputs/[id]/delete.ts | 16 ++-- .../api/event-type-custom-inputs/[id]/edit.ts | 31 ++++--- .../event-type-custom-inputs/[id]/index.ts | 12 +-- pages/api/event-type-custom-inputs/index.ts | 6 +- pages/api/event-type-custom-inputs/new.ts | 23 +++--- pages/api/event-types/[id]/delete.ts | 19 +++-- pages/api/event-types/[id]/edit.ts | 34 +++++--- pages/api/event-types/[id]/index.ts | 12 +-- pages/api/event-types/index.ts | 12 +-- pages/api/event-types/new.ts | 6 +- pages/api/memberships/[id]/delete.ts | 16 ++-- pages/api/memberships/[id]/edit.ts | 26 +++--- pages/api/memberships/[id]/index.ts | 12 +-- pages/api/memberships/index.ts | 6 +- pages/api/memberships/new.ts | 16 ++-- pages/api/schedules/[id]/delete.ts | 13 +-- pages/api/schedules/[id]/edit.ts | 26 +++--- pages/api/schedules/[id]/index.ts | 12 +-- pages/api/schedules/index.ts | 6 +- pages/api/schedules/new.ts | 16 ++-- pages/api/selected-calendars/[id]/delete.ts | 16 ++-- pages/api/selected-calendars/[id]/edit.ts | 26 +++--- pages/api/selected-calendars/[id]/index.ts | 12 +-- pages/api/selected-calendars/index.ts | 6 +- pages/api/selected-calendars/new.ts | 18 +++-- pages/api/teams/[id]/delete.ts | 36 +++++---- pages/api/teams/[id]/edit.ts | 51 ++++++------ pages/api/teams/[id]/index.ts | 35 ++++---- pages/api/teams/index.ts | 21 +++-- pages/api/teams/new.ts | 27 ++++--- pages/api/users/[id]/delete.ts | 40 +++++----- pages/api/users/[id]/edit.ts | 53 ++++++------ pages/api/users/[id]/index.ts | 43 +++++----- pages/api/users/index.ts | 27 ++++--- pages/api/users/new.ts | 35 ++++---- prettier.rc.js | 7 ++ tests/api-keys/[id]/api-key.id.delete.test.ts | 26 +++--- tests/api-keys/[id]/api-key.id.edit.test.ts | 44 ++++++---- tests/api-keys/[id]/api-key.id.index.test.ts | 15 ++-- tests/api-keys/api-key.index.test.ts | 14 +++- tests/api-keys/api-key.new.test.ts | 30 ++++--- tests/bookings/[id]/booking.id.edit.test.ts | 46 ++++++++--- tests/bookings/[id]/booking.id.index.test.ts | 7 +- tests/bookings/booking.index.test.ts | 14 +++- tests/bookings/booking.new.test.ts | 30 ++++--- .../[id]/event-type.id.edit.test.ts | 46 ++++++++--- .../[id]/event-type.id.index.test.ts | 2 - tests/event-types/event-type.index.test.ts | 3 +- tests/event-types/event-type.new.test.ts | 16 ++-- tests/teams/[id]/team.id.edit.test.ts | 39 ++++++--- tests/teams/[id]/team.id.index.test.ts | 2 - tests/users/[id]/user.id.edit.test.ts | 46 ++++++++--- tests/users/[id]/user.id.index.test.ts | 11 ++- tsconfig.json | 21 ++--- 126 files changed, 1240 insertions(+), 992 deletions(-) create mode 100644 .prettierignore create mode 100644 lib/types.ts create mode 100644 lib/validations/shared/baseApiParams.ts create mode 100644 prettier.rc.js diff --git a/.eslintrc.json b/.eslintrc.json index 176de0b130..0378cf43af 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,15 +1,17 @@ // FIXME: import eslint-config-calcom-base from '@calcom/config/eslint { - "root": true, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@next/next/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { "project": ["./tsconfig.json"] }, - "plugins": [ - "@typescript-eslint" - ], - "ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"] -} \ No newline at end of file + "root": true, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "plugin:@next/next/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { "project": ["./tsconfig.json"] }, + "plugins": ["@typescript-eslint", "prettier"], + "rules": { + "prettier/prettier": "error" + }, + "ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..9e622a406d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +.next/ +coverage/ +node_modules/ \ No newline at end of file diff --git a/README.md b/README.md index dc598bf1e8..2ede2ddbc9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ It doesn't have react or react-dom as a dependency, and will only be used by a r - `api.cal.com/v1` - `api.cal.com/api/v1` - ## API Endpoint Validation ### Zod @@ -32,7 +31,6 @@ We also use this useful helper library that let's us wrap our endpoints in a val We aim to provide a fully tested API for our peace of mind, this is accomplished by using jest + node-mocks-http - ## Next.config.js ### Redirects @@ -40,15 +38,14 @@ We aim to provide a fully tested API for our peace of mind, this is accomplished Since this will only support an API, we redirect the requests to root to the /api folder. We also added a redirect for future-proofing API versioning when we might need it, without having to resort to dirty hacks like a v1/v2 folders with lots of duplicated code, instead we redirect /api/v*/:rest to /api/:rest?version=* - The priority is the booking-related API routes so people can build their own booking flow, then event type management routes, then availability management routes etc - How to add a new model or endpoint Basically there's three places of the codebase you need to think about for each feature. /pages/api/ + - This is the most important one, and where your endpoint will live. You will leverage nextjs dynamic routes and expose one file for each endpoint you want to support ideally. ## How the codebase is organized. @@ -66,7 +63,6 @@ GET pages/api/endpoint/[id]/index.ts - Read All of your resource PATCH pages/api/endpoint/[id]/edit.ts - Create new resource DELETE pages/api/endpoint/[id]/delete.ts - Create new resource - ## `/tests/` This is where all your endpoint's tests live, we mock prisma calls. We aim for at least 50% global coverage. Test each of your endpoints. diff --git a/jest.config.ts b/jest.config.ts index d52a95bf87..7923b4cacc 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -7,10 +7,8 @@ const config = { clearMocks: true, coverageDirectory: "./coverage", collectCoverage: true, - "collectCoverageFrom": [ - "pages/api/**/*.ts" - ], - + collectCoverageFrom: ["pages/api/**/*.ts"], + // An array of regexp pattern strings used to skip coverage collection // coveragePathIgnorePatterns: [ // "/node_modules/" @@ -20,12 +18,7 @@ const config = { // coverageProvider: "babel", // A list of reporter names that Jest uses when writing coverage reports - coverageReporters: [ - "json", - "text", - "lcov", - "clover" - ], + coverageReporters: ["json", "text", "lcov", "clover"], // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { @@ -42,34 +35,19 @@ const config = { // Make calling deprecated APIs throw helpful error messages errorOnDeprecated: true, - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // A set of global variables that need to be available in all test environments - // globals: {}, - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. maxWorkers: "50%", - - moduleNameMapper: { "^@lib/(.*)$": "/lib/$1", "^@api/(.*)$": "/pages/api/$1", }, - // The paths to modules that run some code to configure or set up the testing environment before each test // setupFiles: [], // A list of paths to modules that run some code to configure or set up the testing framework before each test - setupFilesAfterEnv: ['/jest.setup.ts'], + setupFilesAfterEnv: ["/jest.setup.ts"], // The number of seconds after which a test is considered as slow and reported as such in the results. slowTestThreshold: 0.1, diff --git a/lib/helpers/addRequestid.ts b/lib/helpers/addRequestid.ts index 2096927a1e..af151e00cc 100644 --- a/lib/helpers/addRequestid.ts +++ b/lib/helpers/addRequestid.ts @@ -1,9 +1,9 @@ -import { NextMiddleware } from "next-api-middleware"; import { nanoid } from "nanoid"; +import { NextMiddleware } from "next-api-middleware"; export const addRequestId: NextMiddleware = async (_req, res, next) => { - // Apply header - res.setHeader("X-Response-ID", nanoid()); - // Let remaining middleware and API route execute - await next(); -}; \ No newline at end of file + // Apply header + res.setHeader("Calcom-Response-ID", nanoid()); + // Let remaining middleware and API route execute + await next(); +}; diff --git a/lib/helpers/captureErrors.ts b/lib/helpers/captureErrors.ts index b78174f36a..9229ad92d8 100644 --- a/lib/helpers/captureErrors.ts +++ b/lib/helpers/captureErrors.ts @@ -1,5 +1,5 @@ -import { NextMiddleware } from "next-api-middleware"; import * as Sentry from "@sentry/nextjs"; +import { NextMiddleware } from "next-api-middleware"; export const captureErrors: NextMiddleware = async (_req, res, next) => { try { @@ -7,10 +7,8 @@ export const captureErrors: NextMiddleware = async (_req, res, next) => { // middleware and the API route handler await next(); } catch (err) { - const eventId = Sentry.captureException(err); - console.log(eventId) + Sentry.captureException(err); res.status(500); res.json({ error: err }); } }; - diff --git a/lib/helpers/httpMethods.ts b/lib/helpers/httpMethods.ts index 4bfeb1b1fe..d19102d4dc 100644 --- a/lib/helpers/httpMethods.ts +++ b/lib/helpers/httpMethods.ts @@ -1,19 +1,17 @@ import { NextMiddleware } from "next-api-middleware"; -export const httpMethod = ( - allowedHttpMethod: "GET" | "POST" | "PATCH" | "DELETE" -): NextMiddleware => { +export const httpMethod = (allowedHttpMethod: "GET" | "POST" | "PATCH" | "DELETE"): NextMiddleware => { return async function (req, res, next) { if (req.method === allowedHttpMethod || req.method == "OPTIONS") { await next(); } else { - res.status(404); + res.status(405).json({ message: `Only ${allowedHttpMethod} Method allowed` }); res.end(); } }; }; -export const postOnly = httpMethod("POST"); -export const getOnly = httpMethod("GET"); -export const patchOnly = httpMethod("PATCH"); -export const deleteOnly = httpMethod("DELETE"); \ No newline at end of file +export const HTTP_POST = httpMethod("POST"); +export const HTTP_GET = httpMethod("GET"); +export const HTTP_PATCH = httpMethod("PATCH"); +export const HTTP_DELETE = httpMethod("DELETE"); diff --git a/lib/helpers/verifyApiKey.ts b/lib/helpers/verifyApiKey.ts index ffc602dcde..0da9a2090b 100644 --- a/lib/helpers/verifyApiKey.ts +++ b/lib/helpers/verifyApiKey.ts @@ -1,20 +1,23 @@ import { NextMiddleware } from "next-api-middleware"; + // import { nanoid } from "nanoid"; import prisma from "@calcom/prisma"; const dateInPast = function (firstDate: Date, secondDate: Date) { - if (firstDate.setHours(0, 0, 0, 0) <= secondDate.setHours(0, 0, 0, 0)) { - return true; - } -} + if (firstDate.setHours(0, 0, 0, 0) <= secondDate.setHours(0, 0, 0, 0)) { + return true; + } +}; const today = new Date(); export const verifyApiKey: NextMiddleware = async (req, res, next) => { - const apiKey = await prisma.apiKey.findUnique({ where: { id: req.query.apiKey as string } }); - if (!apiKey) { - res.status(400).json({ error: 'Your api key is not valid' }); - throw new Error('No api key found'); - } - if (apiKey.expiresAt && dateInPast(apiKey.expiresAt, today)) await next(); - else res.status(400).json({ error: 'Your api key is not valid' }); + const apiKey = await prisma.apiKey.findUnique({ where: { id: req.query.apiKey as string } }); + if (!apiKey) { + res.status(400).json({ error: "Your api key is not valid" }); + throw new Error("No api key found"); + } + if (apiKey.expiresAt && apiKey.userId && dateInPast(apiKey.expiresAt, today)) { + res.setHeader("Calcom-User-ID", apiKey.userId); + await next(); + } else res.status(400).json({ error: "Your api key is not valid" }); }; diff --git a/lib/helpers/withMiddleware.ts b/lib/helpers/withMiddleware.ts index 7d94e5da7a..c410882081 100644 --- a/lib/helpers/withMiddleware.ts +++ b/lib/helpers/withMiddleware.ts @@ -1,19 +1,22 @@ import { label } from "next-api-middleware"; + import { addRequestId } from "./addRequestid"; import { captureErrors } from "./captureErrors"; +import { HTTP_POST, HTTP_DELETE, HTTP_PATCH, HTTP_GET, httpMethod } from "./httpMethods"; import { verifyApiKey } from "./verifyApiKey"; -import { postOnly, deleteOnly, patchOnly, getOnly } from "./httpMethods"; + const withMiddleware = label( { - getOnly, - patchOnly, - postOnly, - deleteOnly, + HTTP_GET, + HTTP_PATCH, + HTTP_POST, + HTTP_DELETE, addRequestId, verifyApiKey, - sentry: captureErrors, // <-- Optionally alias middleware + sentry: captureErrors, + httpMethod: httpMethod("GET" || "DELETE" || "PATCH" || "POST"), }, - ["sentry","verifyApiKey"] // <-- Provide a list of middleware to call automatically + ["sentry", "verifyApiKey", "httpMethod", "addRequestId"] // <-- Provide a list of middleware to call automatically ); -export { withMiddleware }; \ No newline at end of file +export { withMiddleware }; diff --git a/lib/types.ts b/lib/types.ts new file mode 100644 index 0000000000..fde9ba7e87 --- /dev/null +++ b/lib/types.ts @@ -0,0 +1,22 @@ +import { User, ApiKey } from "@calcom/prisma/client"; + +// Base response, used for all responses +export type BaseResponse = { + message?: string; + error?: Error; +}; +// User +export type UserResponse = BaseResponse & { + data?: Partial; +}; +export type UsersResponse = BaseResponse & { + data?: Partial[]; +}; + +// API Key +export type ApiKeyResponse = BaseResponse & { + data?: Partial; +}; +export type ApiKeysResponse = BaseResponse & { + data?: Partial[]; +}; diff --git a/lib/utils/stringifyISODate.ts b/lib/utils/stringifyISODate.ts index 17be60bed7..cf21cd804b 100644 --- a/lib/utils/stringifyISODate.ts +++ b/lib/utils/stringifyISODate.ts @@ -1,4 +1,4 @@ -export const stringifyISODate = (date: Date|undefined): string => { - return `${date?.toISOString()}` -} -// TODO: create a function that takes an object and returns a stringified version of dates of it. \ No newline at end of file +export const stringifyISODate = (date: Date | undefined): string => { + return `${date?.toISOString()}`; +}; +// TODO: create a function that takes an object and returns a stringified version of dates of it. diff --git a/lib/validations/apiKey.ts b/lib/validations/apiKey.ts index a8d89d78f3..2d93b31e09 100644 --- a/lib/validations/apiKey.ts +++ b/lib/validations/apiKey.ts @@ -1,19 +1,16 @@ import { withValidation } from "next-validations"; -import { z } from "zod"; -const schemaApiKey = z - .object({ - // We need to cast the date as strings as when we get it from the json response - // we serve in api it is a string too (JSON doesn't directly support Date types) - createdAt: z.date().optional().or(z.string().optional()), - expiresAt: z.date().optional(), // default is 30 days - note: z.string().min(1).optional(), - }) - .strict(); // Adding strict so that we can disallow passing in extra fields -const withValidApiKey = withValidation({ - schema: schemaApiKey, +import { _ApiKeyModel as ApiKey } from "@calcom/prisma/zod"; + +export const schemaApiKeyBodyParams = ApiKey.omit({ id: true, userId: true, createdAt: true }); + +export const schemaApiKeyPublic = ApiKey.omit({ + id: true, + userId: true, +}); + +export const withValidApiKey = withValidation({ + schema: schemaApiKeyBodyParams, type: "Zod", mode: "body", }); - -export { schemaApiKey, withValidApiKey }; diff --git a/lib/validations/availability.ts b/lib/validations/availability.ts index 1bffc5acec..24f692118b 100644 --- a/lib/validations/availability.ts +++ b/lib/validations/availability.ts @@ -7,13 +7,13 @@ const schemaAvailability = z userId: z.number(), eventTypeId: z.number(), scheduleId: z.number(), - + days: z.array(z.number()), date: z.date().or(z.string()), startTime: z.string(), endTime: z.string(), }) - .strict(); + .strict(); const withValidAvailability = withValidation({ schema: schemaAvailability, type: "Zod", diff --git a/lib/validations/booking-reference.ts b/lib/validations/booking-reference.ts index 3a7298b9ac..fc1fe225c6 100644 --- a/lib/validations/booking-reference.ts +++ b/lib/validations/booking-reference.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaBookingReference = z - .object({}) - .strict(); +const schemaBookingReference = z.object({}).strict(); const withValidBookingReference = withValidation({ schema: schemaBookingReference, type: "Zod", diff --git a/lib/validations/booking.ts b/lib/validations/booking.ts index 7c07aac283..74834e9e0e 100644 --- a/lib/validations/booking.ts +++ b/lib/validations/booking.ts @@ -15,7 +15,7 @@ const schemaBooking = z rejected: z.boolean().default(false), paid: z.boolean().default(false), }) - .strict(); + .strict(); const withValidBooking = withValidation({ schema: schemaBooking, type: "Zod", diff --git a/lib/validations/credential.ts b/lib/validations/credential.ts index b0b142bfd3..4f371491d4 100644 --- a/lib/validations/credential.ts +++ b/lib/validations/credential.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaCredential = z - .object({}) - .strict(); +const schemaCredential = z.object({}).strict(); const withValidCredential = withValidation({ schema: schemaCredential, type: "Zod", diff --git a/lib/validations/daily-event-reference.ts b/lib/validations/daily-event-reference.ts index 48a8a93e62..3fcdcb2553 100644 --- a/lib/validations/daily-event-reference.ts +++ b/lib/validations/daily-event-reference.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaDailyEventReference = z - .object({}) - .strict(); +const schemaDailyEventReference = z.object({}).strict(); const withValidDailyEventReference = withValidation({ schema: schemaDailyEventReference, type: "Zod", diff --git a/lib/validations/destination-calendar.ts b/lib/validations/destination-calendar.ts index 34fa856897..541d9db59f 100644 --- a/lib/validations/destination-calendar.ts +++ b/lib/validations/destination-calendar.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaDestinationCalendar = z - .object({}) - .strict(); +const schemaDestinationCalendar = z.object({}).strict(); const withValidDestinationCalendar = withValidation({ schema: schemaDestinationCalendar, type: "Zod", diff --git a/lib/validations/eventType.ts b/lib/validations/eventType.ts index 34764a21ee..7d96883133 100644 --- a/lib/validations/eventType.ts +++ b/lib/validations/eventType.ts @@ -8,7 +8,7 @@ const schemaEventType = z length: z.number().min(1).max(1440), // max is a full day. description: z.string().min(3).optional(), }) - .strict(); + .strict(); const withValidEventType = withValidation({ schema: schemaEventType, type: "Zod", diff --git a/lib/validations/membership.ts b/lib/validations/membership.ts index 3d52743955..4b4a5a0c33 100644 --- a/lib/validations/membership.ts +++ b/lib/validations/membership.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaMembership = z - .object({}) - .strict(); +const schemaMembership = z.object({}).strict(); const withValidMembership = withValidation({ schema: schemaMembership, type: "Zod", diff --git a/lib/validations/payment.ts b/lib/validations/payment.ts index b9f019fe0d..f1ed09dcde 100644 --- a/lib/validations/payment.ts +++ b/lib/validations/payment.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaPayment = z - .object({}) - .strict(); +const schemaPayment = z.object({}).strict(); const withValidPayment = withValidation({ schema: schemaPayment, type: "Zod", diff --git a/lib/validations/schedule.ts b/lib/validations/schedule.ts index 9a0b0f286f..5c8e887271 100644 --- a/lib/validations/schedule.ts +++ b/lib/validations/schedule.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaSchedule = z - .object({}) - .strict(); +const schemaSchedule = z.object({}).strict(); const withValidSchedule = withValidation({ schema: schemaSchedule, type: "Zod", diff --git a/lib/validations/selected-calendar.ts b/lib/validations/selected-calendar.ts index b1646e1047..29ffdb9c11 100644 --- a/lib/validations/selected-calendar.ts +++ b/lib/validations/selected-calendar.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaSelectedCalendar = z - .object({}) - .strict(); +const schemaSelectedCalendar = z.object({}).strict(); const withValidSelectedCalendar = withValidation({ schema: schemaSelectedCalendar, type: "Zod", diff --git a/lib/validations/shared/baseApiParams.ts b/lib/validations/shared/baseApiParams.ts new file mode 100644 index 0000000000..03b13838ee --- /dev/null +++ b/lib/validations/shared/baseApiParams.ts @@ -0,0 +1,13 @@ +import { z } from "zod"; + +// Extracted out as utility function so can be reused +// at different endpoints that require this validation. +export const baseApiParams = z + .object({ + // since we added apiKey as query param this is required by next-validations helper + // for query params to work properly and not fail. + apiKey: z.string().cuid(), + // version required for supporting /v1/ redirect to query in api as *?version=1 + version: z.string().optional(), + }) + .strict(); diff --git a/lib/validations/shared/queryIdString.ts b/lib/validations/shared/queryIdString.ts index e89986dca5..718e26123f 100644 --- a/lib/validations/shared/queryIdString.ts +++ b/lib/validations/shared/queryIdString.ts @@ -1,23 +1,18 @@ import { withValidation } from "next-validations"; import { z } from "zod"; +import { baseApiParams } from "./baseApiParams"; + // Extracted out as utility function so can be reused // at different endpoints that require this validation. -const schemaQueryIdAsString = z - .object({ - // since we added apiKey as query param this is required by next-validations helper - // for query params to work properly and not fail. - apiKey: z.string().cuid(), - // since nextjs parses query params as strings, - // we need to cast them to numbers using z.transform() and parseInt() - id: z.string() +export const schemaQueryIdAsString = baseApiParams + .extend({ + id: z.string(), }) .strict(); -const withValidQueryIdString = withValidation({ +export const withValidQueryIdString = withValidation({ schema: schemaQueryIdAsString, type: "Zod", mode: "query", }); - -export { schemaQueryIdAsString, withValidQueryIdString }; diff --git a/lib/validations/shared/queryIdTransformParseInt.ts b/lib/validations/shared/queryIdTransformParseInt.ts index b1f2eb4835..b97d126d43 100644 --- a/lib/validations/shared/queryIdTransformParseInt.ts +++ b/lib/validations/shared/queryIdTransformParseInt.ts @@ -1,15 +1,12 @@ import { withValidation } from "next-validations"; import { z } from "zod"; +import { baseApiParams } from "./baseApiParams"; + // Extracted out as utility function so can be reused // at different endpoints that require this validation. -const schemaQueryIdParseInt = z - .object({ - // since we added apiKey as query param this is required by next-validations helper - // for query params to work properly and not fail. - apiKey: z.string().cuid(), - // since nextjs parses query params as strings, - // we need to cast them to numbers using z.transform() and parseInt() +export const schemaQueryIdParseInt = baseApiParams + .extend({ id: z .string() .regex(/^\d+$/) @@ -17,10 +14,8 @@ const schemaQueryIdParseInt = z }) .strict(); -const withValidQueryIdTransformParseInt = withValidation({ +export const withValidQueryIdTransformParseInt = withValidation({ schema: schemaQueryIdParseInt, type: "Zod", mode: "query", }); - -export { schemaQueryIdParseInt, withValidQueryIdTransformParseInt }; diff --git a/lib/validations/team.ts b/lib/validations/team.ts index 935f49ac1e..44cb1329a8 100644 --- a/lib/validations/team.ts +++ b/lib/validations/team.ts @@ -9,7 +9,7 @@ const schemaTeam = z bio: z.string().min(3).optional(), logo: z.string().optional(), }) - .strict(); + .strict(); const withValidTeam = withValidation({ schema: schemaTeam, type: "Zod", diff --git a/lib/validations/user.ts b/lib/validations/user.ts index b0fd00848c..2058a20c2e 100644 --- a/lib/validations/user.ts +++ b/lib/validations/user.ts @@ -1,63 +1,29 @@ import { withValidation } from "next-validations"; -import { z } from "zod"; -import { schemaEventType } from "./eventType"; -import { schemaApiKey } from "./apiKey"; -import { schemaDestinationCalendar } from "./destination-calendar"; -import { schemaWebhook } from "./webhook"; -import { schemaAvailability } from "./availability"; -import { schemaSelectedCalendar } from "./selected-calendar"; -import { schemaBooking } from "./booking"; -import { schemaMembership } from "./membership"; -import { schemaSchedule } from "./schedule"; -import { schemaCredential } from "./credential"; +import { _UserModel as User } from "@calcom/prisma/zod"; -const schemaUser = z - .object({ - username: z.string().min(3), - name: z.string().min(3), - email: z.string().email(), // max is a full day. - emailVerified: z.date().optional(), - password: z.string().optional(), - bio: z.string().min(3).optional(), - avatar: z.string().optional(), - timeZone: z.string().default("Europe/London"), - weekStart: z.string().default("Sunday"), - bufferTime: z.number().default(0), - hideBranding: z.boolean().default(false), - theme: z.string().optional(), - trialEndsAt: z.date().optional(), - eventTypes: z.array((schemaEventType)).optional(), - credentials: z.array((schemaCredential)).optional(), - teams: z.array((schemaMembership)).optional(), - bookings: z.array((schemaBooking)).optional(), - schedules: z.array((schemaSchedule)).optional(), - defaultScheduleId: z.number().optional(), - selectedCalendars: z.array((schemaSelectedCalendar)).optional(), - completedOnboarding: z.boolean().default(false), - locale: z.string().optional(), - timeFormat: z.number().optional().default(12), - twoFactorEnabled: z.boolean().default(false), - twoFactorSecret: z.string().optional(), - identityProvider: z.enum(["CAL", "SAML", "GOOGLE"]).optional().default("CAL"), - identityProviderId: z.string().optional(), - availability: z.array((schemaAvailability)).optional(), - invitedTo: z.number().optional(), - plan: z.enum(['FREE', 'TRIAL', 'PRO']).default("TRIAL"), - webhooks: z.array((schemaWebhook)).optional(), - brandColor: z.string().default("#292929"), - darkBrandColor: z.string().default("#fafafa"), - destinationCalendar: z.array(schemaDestinationCalendar).optional(), // FIXME: instanceof doesnt work here - away: z.boolean().default(false), - metadata: z.object({}).optional(), - verified: z.boolean().default(false), - apiKeys: z.array((schemaApiKey)).optional(), - }) - .strict(); -const withValidUser = withValidation({ - schema: schemaUser, +export const schemaUserBodyParams = User.omit({ + id: true, + createdAt: true, + password: true, + twoFactorEnabled: true, + twoFactorSecret: true, +}); + +export const schemaUserPublic = User.omit({ + identityProvider: true, + identityProviderId: true, + plan: true, + metadata: true, + password: true, + twoFactorEnabled: true, + twoFactorSecret: true, + trialEndsAt: true, + completedOnboarding: true, +}); + +export const withValidUser = withValidation({ + schema: schemaUserBodyParams, type: "Zod", mode: "body", }); - -export { schemaUser, withValidUser }; diff --git a/lib/validations/webhook.ts b/lib/validations/webhook.ts index 1b1a35a2da..457a818815 100644 --- a/lib/validations/webhook.ts +++ b/lib/validations/webhook.ts @@ -1,9 +1,7 @@ import { withValidation } from "next-validations"; import { z } from "zod"; -const schemaWebhook = z - .object({}) - .strict(); +const schemaWebhook = z.object({}).strict(); const withValidWebhook = withValidation({ schema: schemaWebhook, diff --git a/next.config.js b/next.config.js index 7cd0ff53d7..1962fe9a8e 100644 --- a/next.config.js +++ b/next.config.js @@ -1,8 +1,6 @@ // https://www.npmjs.com/package/next-transpile-modules // This makes our @calcom/prisma package from the monorepo to be transpiled and usable by API -const withTM = require("next-transpile-modules")([ - "@calcom/prisma", -]); +const withTM = require("next-transpile-modules")(["@calcom/prisma", "@calcom/lib"]); // use something like withPlugins([withTM], {}) if more plugins added later. diff --git a/package.json b/package.json index feaee290bb..79ed5ea648 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "start": "next start", "build": "next build", "lint": "next lint", - "lint-fix": "next lint --fix", + "lint-fix": "next lint --fix && prettier --write .", "test": "jest --detectOpenHandles", "type-check": "tsc --pretty --noEmit", "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", diff --git a/pages/_middleware.ts b/pages/_middleware.ts index 624d392043..59f0b1501f 100644 --- a/pages/_middleware.ts +++ b/pages/_middleware.ts @@ -3,7 +3,8 @@ import { NextRequest, NextResponse } from "next/server"; // Not much useful yet as prisma.client can't be used in the middlewares (client is not available) // For now we just throw early if no apiKey is passed, // but we could also check if the apiKey is valid if we had prisma here. -export async function requireApiKeyAsQueryParams({ nextUrl }: NextRequest) { + +export default async function requireApiKeyAsQueryParams({ nextUrl }: NextRequest) { const response = NextResponse.next(); const apiKey = nextUrl.searchParams.get("apiKey"); diff --git a/pages/api/api-keys/[id]/delete.ts b/pages/api/api-keys/[id]/delete.ts index 722705a303..dbe8250fe2 100644 --- a/pages/api/api-keys/[id]/delete.ts +++ b/pages/api/api-keys/[id]/delete.ts @@ -1,7 +1,7 @@ - import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; @@ -13,8 +13,7 @@ type ResponseData = { export async function deleteApiKey(req: NextApiRequest, res: NextApiResponse) { const safe = await schemaQueryIdAsString.safeParse(req.query); if (safe.success) { - const data = await prisma.apiKey - .delete({ where: { id: safe.data.id } }) + const data = await prisma.apiKey.delete({ where: { id: safe.data.id } }); // We only remove the apiKey type from the database if there's an existing resource. if (data) res.status(200).json({ message: `ApiKey with id: ${safe.data.id} deleted successfully` }); // This catches the error thrown by prisma.apiKey.delete() if the resource is not found. @@ -22,8 +21,4 @@ export async function deleteApiKey(req: NextApiRequest, res: NextApiResponse) { - const { query, body, method } = req; + const { query, body } = req; const safeQuery = await schemaQueryIdAsString.safeParse(query); - const safeBody = await schemaApiKey.safeParse(body); + const safeBody = await schemaApiKeyBodyParams.safeParse(body); if (safeQuery.success && safeBody.success) { - const data = await prisma.apiKey.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) + const data = await prisma.apiKey.update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }); if (data) res.status(200).json({ data }); - else (error: unknown) => res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }) + else + (error: unknown) => + res + .status(404) + .json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }); } } -export default withMiddleware("patchOnly","addRequestId")( - withValidQueryIdString( - withValidApiKey( - editApiKey) - ) -); +export default withMiddleware( + "HTTP_PATCH", + "addRequestId" +)(withValidQueryIdString(withValidApiKey(editApiKey))); diff --git a/pages/api/api-keys/[id]/index.ts b/pages/api/api-keys/[id]/index.ts index 18d6dbcc69..36b9203667 100644 --- a/pages/api/api-keys/[id]/index.ts +++ b/pages/api/api-keys/[id]/index.ts @@ -1,14 +1,13 @@ -import prisma from "@calcom/prisma"; - -import { ApiKey } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; +import prisma from "@calcom/prisma"; +import { ApiKey } from "@calcom/prisma/client"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; +import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; type ResponseData = { data?: ApiKey; - message?: string; error?: unknown; }; @@ -18,13 +17,8 @@ export async function apiKeyById(req: NextApiRequest, res: NextApiResponse) { - const safe = schemaApiKey.safeParse(req.body); + const safe = schemaApiKeyBodyParams.safeParse(req.body); if (safe.success) { - const data = await prisma.apiKey - .create({ data: safe.data }) - if (data) res.status(201).json({ data }) - else (error: unknown) => res.status(400).json({ error: { message: "Could not create apiKey type", error: error } }); + const data = await prisma.apiKey.create({ data: safe.data }); + if (data) res.status(201).json({ data }); + else + (error: unknown) => res.status(400).json({ error: { message: "Could not create apiKey type", error } }); } } -export default withMiddleware("addRequestId","postOnly")( - withValidApiKey( - createApiKey - ) -); +export default withMiddleware("addRequestId", "HTTP_POST")(withValidApiKey(createApiKey)); diff --git a/pages/api/attendees/[id]/delete.ts b/pages/api/attendees/[id]/delete.ts index 21c0efaff4..99ca9eef3f 100644 --- a/pages/api/attendees/[id]/delete.ts +++ b/pages/api/attendees/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,12 +16,11 @@ export async function attendee(req: NextApiRequest, res: NextApiResponse { - res.status(200).json({ data: attendee }); - }).catch(error => { - res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }) - }); + await prisma.attendee + .update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }) + .then((attendee) => { + res.status(200).json({ data: attendee }); + }) + .catch((error) => { + 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 attendees" }); + } else res.status(405).json({ message: "Only PATCH Method allowed for updating attendees" }); } export default withValidQueryIdTransformParseInt(withValidAttendee(editAttendee)); diff --git a/pages/api/attendees/[id]/index.ts b/pages/api/attendees/[id]/index.ts index a5521dd057..6fc30b78f2 100644 --- a/pages/api/attendees/[id]/index.ts +++ b/pages/api/attendees/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { Attendee } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { Attendee } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: Attendee; @@ -14,7 +17,7 @@ type ResponseData = { export async function attendee(req: NextApiRequest, res: NextApiResponse) { const { query, method } = req; const safe = await schemaQueryIdParseInt.safeParse(query); - + if (method === "GET" && safe.success) { const attendee = await prisma.attendee.findUnique({ where: { id: safe.data.id } }); diff --git a/pages/api/attendees/index.ts b/pages/api/attendees/index.ts index 1a105dd52d..c5ac16eb09 100644 --- a/pages/api/attendees/index.ts +++ b/pages/api/attendees/index.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { Attendee } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { Attendee } from "@calcom/prisma/client"; + type ResponseData = { data?: Attendee[]; error?: unknown; diff --git a/pages/api/attendees/new.ts b/pages/api/attendees/new.ts index 12762f14f0..f01d7a3dbe 100644 --- a/pages/api/attendees/new.ts +++ b/pages/api/attendees/new.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { Attendee } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { Attendee } from "@calcom/prisma/client"; + import { schemaAttendee, withValidAttendee } from "@lib/validations/attendee"; type ResponseData = { @@ -14,13 +14,13 @@ type ResponseData = { async function createAttendee(req: NextApiRequest, res: NextApiResponse) { const { body, method } = req; const safe = schemaAttendee.safeParse(body); - + if (method === "POST" && safe.success) { - await prisma.attendee - .create({ data: safe.data }) - .then((attendee) => res.status(201).json({ data: attendee })) - .catch((error) => res.status(400).json({ message: "Could not create attendee type", error: error })); - // Reject any other HTTP method than POST + await prisma.attendee + .create({ data: safe.data }) + .then((attendee) => res.status(201).json({ data: attendee })) + .catch((error) => res.status(400).json({ message: "Could not create attendee type", error: error })); + // Reject any other HTTP method than POST } else res.status(405).json({ error: "Only POST Method allowed" }); } diff --git a/pages/api/availabilities/[id]/delete.ts b/pages/api/availabilities/[id]/delete.ts index 43db244859..b59534eb08 100644 --- a/pages/api/availabilities/[id]/delete.ts +++ b/pages/api/availabilities/[id]/delete.ts @@ -1,8 +1,11 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -13,12 +16,12 @@ export async function availability(req: NextApiRequest, res: NextApiResponse { + }) + .then((availability) => { res.status(200).json({ data: availability }); - }).catch(error => { - res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }) + }) + .catch((error) => { + 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 PATCH - } else res.status(405).json({ message: "Only PATCH Method allowed for updating availabilities" }); + // Reject any other HTTP method than PATCH + } else res.status(405).json({ message: "Only PATCH Method allowed for updating availabilities" }); } export default withValidQueryIdTransformParseInt(withValidAvailability(editAvailability)); diff --git a/pages/api/availabilities/[id]/index.ts b/pages/api/availabilities/[id]/index.ts index 7d10930907..8e2573df69 100644 --- a/pages/api/availabilities/[id]/index.ts +++ b/pages/api/availabilities/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { Availability } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { Availability } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: Availability; @@ -14,7 +17,7 @@ type ResponseData = { export async function availability(req: NextApiRequest, res: NextApiResponse) { const { query, method } = req; const safe = await schemaQueryIdParseInt.safeParse(query); - + if (method === "GET" && safe.success) { const availability = await prisma.availability.findUnique({ where: { id: safe.data.id } }); @@ -24,5 +27,4 @@ export async function availability(req: NextApiRequest, res: NextApiResponse res.status(201).json({ data: availability })) - .catch((error) => res.status(400).json({ message: "Could not create availability type", error: error })); + .catch((error) => + res.status(400).json({ message: "Could not create availability type", error: error }) + ); } } else { // Reject any other HTTP method than POST diff --git a/pages/api/booking-references/[id]/delete.ts b/pages/api/booking-references/[id]/delete.ts index 13798382ba..6f7685854f 100644 --- a/pages/api/booking-references/[id]/delete.ts +++ b/pages/api/booking-references/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,12 +16,12 @@ export async function deleteBookingReference(req: NextApiRequest, res: NextApiRe 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 } }) + 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` }); + 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`}); + 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" }); } diff --git a/pages/api/booking-references/[id]/edit.ts b/pages/api/booking-references/[id]/edit.ts index 834574a3a1..b1ecfcee35 100644 --- a/pages/api/booking-references/[id]/edit.ts +++ b/pages/api/booking-references/[id]/edit.ts @@ -1,10 +1,13 @@ -import prisma from "@calcom/prisma"; - -import { BookingReference } from "@calcom/prisma/client"; 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 { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: BookingReference; @@ -18,15 +21,18 @@ export async function editBookingReference(req: NextApiRequest, res: NextApiResp const safeBody = await schemaBookingReference.safeParse(body); if (method === "PATCH" && safeQuery.success && safeBody.success) { - const data = await prisma.bookingReference.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) + 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` }) + 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" }); + } else res.status(405).json({ message: "Only PATCH Method allowed for updating bookingReferences" }); } export default withValidQueryIdTransformParseInt(withValidBookingReference(editBookingReference)); diff --git a/pages/api/booking-references/[id]/index.ts b/pages/api/booking-references/[id]/index.ts index 8a649fb4d9..4e8483b797 100644 --- a/pages/api/booking-references/[id]/index.ts +++ b/pages/api/booking-references/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { BookingReference } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { BookingReference } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: BookingReference; @@ -23,5 +26,4 @@ export async function bookingReference(req: NextApiRequest, res: NextApiResponse } else res.status(405).json({ message: "Only GET Method allowed" }); } - export default withValidQueryIdTransformParseInt(bookingReference); diff --git a/pages/api/booking-references/index.ts b/pages/api/booking-references/index.ts index 460d681ca7..f0244da6bb 100644 --- a/pages/api/booking-references/index.ts +++ b/pages/api/booking-references/index.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { BookingReference } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { BookingReference } from "@calcom/prisma/client"; + type ResponseData = { data?: BookingReference[]; error?: unknown; diff --git a/pages/api/booking-references/new.ts b/pages/api/booking-references/new.ts index e792e3f1c7..319e80404e 100644 --- a/pages/api/booking-references/new.ts +++ b/pages/api/booking-references/new.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { BookingReference } from "@calcom/prisma/client"; 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"; type ResponseData = { @@ -15,11 +15,13 @@ async function createBookingReference(req: NextApiRequest, res: NextApiResponse< 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 + 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" }); } diff --git a/pages/api/bookings/[id]/delete.ts b/pages/api/bookings/[id]/delete.ts index 4150a66613..a2dad90c7e 100644 --- a/pages/api/bookings/[id]/delete.ts +++ b/pages/api/bookings/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,14 +16,14 @@ export async function deleteBooking(req: NextApiRequest, res: NextApiResponse { - 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 }) - }); + 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" }); + res.status(405).json({ message: "Only PATCH Method allowed for updating bookings" }); } } diff --git a/pages/api/bookings/[id]/index.ts b/pages/api/bookings/[id]/index.ts index dbe47a5f91..8311dea842 100644 --- a/pages/api/bookings/[id]/index.ts +++ b/pages/api/bookings/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { Booking } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { Booking } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: Booking; @@ -26,5 +29,4 @@ export async function booking(req: NextApiRequest, res: NextApiResponse 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 + 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" }); } diff --git a/pages/api/daily-event-references/[id]/delete.ts b/pages/api/daily-event-references/[id]/delete.ts index 2a43ab2d7e..77c97782a6 100644 --- a/pages/api/daily-event-references/[id]/delete.ts +++ b/pages/api/daily-event-references/[id]/delete.ts @@ -1,10 +1,12 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; -import { withMiddleware } from "@lib/helpers/withMiddleware"; +import prisma from "@calcom/prisma"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,19 +16,17 @@ type ResponseData = { export async function deleteDailyEventReference(req: NextApiRequest, res: NextApiResponse) { const safe = await schemaQueryIdParseInt.safeParse(req.query); if (safe.success) { - const deletedDailyEventReference = await prisma.dailyEventReference - .delete({ where: { id: safe.data.id } }) + const deletedDailyEventReference = await prisma.dailyEventReference.delete({ + where: { id: safe.data.id }, + }); // We only remove the dailyEventReference type from the database if there's an existing resource. - if (deletedDailyEventReference) res.status(200).json({ message: `dailyEventReference with id: ${safe.data.id} deleted successfully` }); + if (deletedDailyEventReference) + res.status(200).json({ message: `dailyEventReference with id: ${safe.data.id} deleted successfully` }); // This catches the error thrown by prisma.dailyEventReference.delete() if the resource is not found. - else res.status(400).json({ message: `Resource with id:${safe.data.id} was 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" }); } // export default withValidQueryIdTransformParseInt(deleteDailyEventReference); -export default withMiddleware("deleteOnly")( - withValidQueryIdTransformParseInt( - deleteDailyEventReference - ) -); +export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteDailyEventReference)); diff --git a/pages/api/daily-event-references/[id]/edit.ts b/pages/api/daily-event-references/[id]/edit.ts index 30c5bbca78..372e258163 100644 --- a/pages/api/daily-event-references/[id]/edit.ts +++ b/pages/api/daily-event-references/[id]/edit.ts @@ -1,10 +1,16 @@ -import prisma from "@calcom/prisma"; - -import { DailyEventReference } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaDailyEventReference, withValidDailyEventReference } from "@lib/validations/daily-event-reference"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { DailyEventReference } from "@calcom/prisma/client"; + +import { + schemaDailyEventReference, + withValidDailyEventReference, +} from "@lib/validations/daily-event-reference"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: DailyEventReference; @@ -18,15 +24,18 @@ export async function editDailyEventReference(req: NextApiRequest, res: NextApiR const safeBody = await schemaDailyEventReference.safeParse(body); if (method === "PATCH" && safeQuery.success && safeBody.success) { - const data = await prisma.dailyEventReference.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) + const data = await prisma.dailyEventReference.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 }) + 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 dailyEventReferences" }); + } else res.status(405).json({ message: "Only PATCH Method allowed for updating dailyEventReferences" }); } export default withValidQueryIdTransformParseInt(withValidDailyEventReference(editDailyEventReference)); diff --git a/pages/api/daily-event-references/[id]/index.ts b/pages/api/daily-event-references/[id]/index.ts index 166a661dcc..459c4f5381 100644 --- a/pages/api/daily-event-references/[id]/index.ts +++ b/pages/api/daily-event-references/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { DailyEventReference } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { DailyEventReference } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: DailyEventReference; @@ -23,5 +26,4 @@ export async function dailyEventReference(req: NextApiRequest, res: NextApiRespo } else res.status(405).json({ message: "Only GET Method allowed" }); } - export default withValidQueryIdTransformParseInt(dailyEventReference); diff --git a/pages/api/daily-event-references/index.ts b/pages/api/daily-event-references/index.ts index 7d25bba8f1..a5509f8a90 100644 --- a/pages/api/daily-event-references/index.ts +++ b/pages/api/daily-event-references/index.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { DailyEventReference } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { DailyEventReference } from "@calcom/prisma/client"; + type ResponseData = { data?: DailyEventReference[]; error?: unknown; diff --git a/pages/api/daily-event-references/new.ts b/pages/api/daily-event-references/new.ts index 153742739a..5bbc67fb2c 100644 --- a/pages/api/daily-event-references/new.ts +++ b/pages/api/daily-event-references/new.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { DailyEventReference } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaDailyEventReference, withValidDailyEventReference } from "@lib/validations/daily-event-reference"; +import prisma from "@calcom/prisma"; +import { DailyEventReference } from "@calcom/prisma/client"; + +import { + schemaDailyEventReference, + withValidDailyEventReference, +} from "@lib/validations/daily-event-reference"; type ResponseData = { data?: DailyEventReference; @@ -15,11 +18,13 @@ async function createDailyEventReference(req: NextApiRequest, res: NextApiRespon const { body, method } = req; const safe = schemaDailyEventReference.safeParse(body); if (method === "POST" && safe.success) { - await prisma.dailyEventReference - .create({ data: safe.data }) - .then((data) => res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create dailyEventReference type", error: error })); - // Reject any other HTTP method than POST + await prisma.dailyEventReference + .create({ data: safe.data }) + .then((data) => res.status(201).json({ data })) + .catch((error) => + res.status(400).json({ message: "Could not create dailyEventReference type", error: error }) + ); + // Reject any other HTTP method than POST } else res.status(405).json({ error: "Only POST Method allowed" }); } diff --git a/pages/api/destination-calendars/[id]/delete.ts b/pages/api/destination-calendars/[id]/delete.ts index 246d5a58eb..b734fbdf9b 100644 --- a/pages/api/destination-calendars/[id]/delete.ts +++ b/pages/api/destination-calendars/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,12 +16,12 @@ export async function deleteDestinationCalendar(req: NextApiRequest, res: NextAp const { query, method } = req; const safe = await schemaQueryIdParseInt.safeParse(query); if (method === "DELETE" && safe.success && safe.data) { - const destinationCalendar = await prisma.destinationCalendar - .delete({ where: { id: safe.data.id } }) + const destinationCalendar = await prisma.destinationCalendar.delete({ where: { id: safe.data.id } }); // We only remove the destinationCalendar type from the database if there's an existing resource. - if (destinationCalendar) res.status(200).json({ message: `destinationCalendar with id: ${safe.data.id} deleted successfully` }); + if (destinationCalendar) + res.status(200).json({ message: `destinationCalendar with id: ${safe.data.id} deleted successfully` }); // This catches the error thrown by prisma.destinationCalendar.delete() if the resource is not found. - else res.status(400).json({ message: `Resource with id:${safe.data.id} was 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" }); } diff --git a/pages/api/destination-calendars/[id]/edit.ts b/pages/api/destination-calendars/[id]/edit.ts index 5495656d70..09c042b7e1 100644 --- a/pages/api/destination-calendars/[id]/edit.ts +++ b/pages/api/destination-calendars/[id]/edit.ts @@ -1,10 +1,16 @@ -import prisma from "@calcom/prisma"; - -import { DestinationCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaDestinationCalendar, withValidDestinationCalendar } from "@lib/validations/destination-calendar"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { DestinationCalendar } from "@calcom/prisma/client"; + +import { + schemaDestinationCalendar, + withValidDestinationCalendar, +} from "@lib/validations/destination-calendar"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: DestinationCalendar; @@ -18,15 +24,18 @@ export async function editDestinationCalendar(req: NextApiRequest, res: NextApiR const safeBody = await schemaDestinationCalendar.safeParse(body); if (method === "PATCH" && safeQuery.success && safeBody.success) { - const data = await prisma.destinationCalendar.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) + const data = await prisma.destinationCalendar.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 }) + 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 destinationCalendars" }); + } else res.status(405).json({ message: "Only PATCH Method allowed for updating destinationCalendars" }); } export default withValidQueryIdTransformParseInt(withValidDestinationCalendar(editDestinationCalendar)); diff --git a/pages/api/destination-calendars/[id]/index.ts b/pages/api/destination-calendars/[id]/index.ts index 95a44a5edf..fde198f77f 100644 --- a/pages/api/destination-calendars/[id]/index.ts +++ b/pages/api/destination-calendars/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { DestinationCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { DestinationCalendar } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: DestinationCalendar; @@ -23,5 +26,4 @@ export async function destinationCalendar(req: NextApiRequest, res: NextApiRespo } else res.status(405).json({ message: "Only GET Method allowed" }); } - export default withValidQueryIdTransformParseInt(destinationCalendar); diff --git a/pages/api/destination-calendars/index.ts b/pages/api/destination-calendars/index.ts index 3877dbc08a..933ef20568 100644 --- a/pages/api/destination-calendars/index.ts +++ b/pages/api/destination-calendars/index.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { DestinationCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { DestinationCalendar } from "@calcom/prisma/client"; + type ResponseData = { data?: DestinationCalendar[]; error?: unknown; diff --git a/pages/api/destination-calendars/new.ts b/pages/api/destination-calendars/new.ts index 485219322d..483ff56de1 100644 --- a/pages/api/destination-calendars/new.ts +++ b/pages/api/destination-calendars/new.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { DestinationCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaDestinationCalendar, withValidDestinationCalendar } from "@lib/validations/destination-calendar"; +import prisma from "@calcom/prisma"; +import { DestinationCalendar } from "@calcom/prisma/client"; + +import { + schemaDestinationCalendar, + withValidDestinationCalendar, +} from "@lib/validations/destination-calendar"; type ResponseData = { data?: DestinationCalendar; @@ -15,11 +18,13 @@ async function createDestinationCalendar(req: NextApiRequest, res: NextApiRespon const { body, method } = req; const safe = schemaDestinationCalendar.safeParse(body); if (method === "POST" && safe.success) { - await prisma.destinationCalendar - .create({ data: safe.data }) - .then((data) => res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create destinationCalendar type", error: error })); - // Reject any other HTTP method than POST + await prisma.destinationCalendar + .create({ data: safe.data }) + .then((data) => res.status(201).json({ data })) + .catch((error) => + res.status(400).json({ message: "Could not create destinationCalendar type", error: error }) + ); + // Reject any other HTTP method than POST } else res.status(405).json({ error: "Only POST Method allowed" }); } diff --git a/pages/api/event-type-custom-inputs/[id]/delete.ts b/pages/api/event-type-custom-inputs/[id]/delete.ts index d4e8431f51..acccbac7d7 100644 --- a/pages/api/event-type-custom-inputs/[id]/delete.ts +++ b/pages/api/event-type-custom-inputs/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,12 +16,12 @@ export async function deleteEventTypeCustomInput(req: NextApiRequest, res: NextA const { query, method } = req; const safe = await schemaQueryIdParseInt.safeParse(query); if (method === "DELETE" && safe.success && safe.data) { - const eventTypeCustomInput = await prisma.eventTypeCustomInput - .delete({ where: { id: safe.data.id } }) + const eventTypeCustomInput = await prisma.eventTypeCustomInput.delete({ where: { id: safe.data.id } }); // We only remove the eventTypeCustomInput type from the database if there's an existing resource. - if (eventTypeCustomInput) res.status(200).json({ message: `eventTypeCustomInput with id: ${safe.data.id} deleted successfully` }); + if (eventTypeCustomInput) + res.status(200).json({ message: `eventTypeCustomInput with id: ${safe.data.id} deleted successfully` }); // This catches the error thrown by prisma.eventTypeCustomInput.delete() if the resource is not found. - else res.status(400).json({ message: `Resource with id:${safe.data.id} was 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" }); } diff --git a/pages/api/event-type-custom-inputs/[id]/edit.ts b/pages/api/event-type-custom-inputs/[id]/edit.ts index fcb650c906..1c632034c2 100644 --- a/pages/api/event-type-custom-inputs/[id]/edit.ts +++ b/pages/api/event-type-custom-inputs/[id]/edit.ts @@ -1,10 +1,16 @@ -import prisma from "@calcom/prisma"; - -import { EventTypeCustomInput } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaEventTypeCustomInput, withValidEventTypeCustomInput } from "@lib/validations/eventTypeCustomInput"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { EventTypeCustomInput } from "@calcom/prisma/client"; + +import { + schemaEventTypeCustomInput, + withValidEventTypeCustomInput, +} from "@lib/validations/eventTypeCustomInput"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: EventTypeCustomInput; @@ -18,15 +24,18 @@ export async function editEventTypeCustomInput(req: NextApiRequest, res: NextApi const safeBody = await schemaEventTypeCustomInput.safeParse(body); if (method === "PATCH" && safeQuery.success && safeBody.success) { - const data = await prisma.eventTypeCustomInput.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) + const data = await prisma.eventTypeCustomInput.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 }) + 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 eventTypeCustomInputs" }); + } else res.status(405).json({ message: "Only PATCH Method allowed for updating eventTypeCustomInputs" }); } export default withValidQueryIdTransformParseInt(withValidEventTypeCustomInput(editEventTypeCustomInput)); diff --git a/pages/api/event-type-custom-inputs/[id]/index.ts b/pages/api/event-type-custom-inputs/[id]/index.ts index c53b2e4c06..47170af37d 100644 --- a/pages/api/event-type-custom-inputs/[id]/index.ts +++ b/pages/api/event-type-custom-inputs/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { EventTypeCustomInput } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { EventTypeCustomInput } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: EventTypeCustomInput; @@ -23,5 +26,4 @@ export async function eventTypeCustomInput(req: NextApiRequest, res: NextApiResp } else res.status(405).json({ message: "Only GET Method allowed" }); } - export default withValidQueryIdTransformParseInt(eventTypeCustomInput); diff --git a/pages/api/event-type-custom-inputs/index.ts b/pages/api/event-type-custom-inputs/index.ts index 733539064e..b39cd14bca 100644 --- a/pages/api/event-type-custom-inputs/index.ts +++ b/pages/api/event-type-custom-inputs/index.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { EventTypeCustomInput } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { EventTypeCustomInput } from "@calcom/prisma/client"; + type ResponseData = { data?: EventTypeCustomInput[]; error?: unknown; diff --git a/pages/api/event-type-custom-inputs/new.ts b/pages/api/event-type-custom-inputs/new.ts index abdb410070..e2a4078a59 100644 --- a/pages/api/event-type-custom-inputs/new.ts +++ b/pages/api/event-type-custom-inputs/new.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { EventTypeCustomInput } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaEventTypeCustomInput, withValidEventTypeCustomInput } from "@lib/validations/eventTypeCustomInput"; +import prisma from "@calcom/prisma"; +import { EventTypeCustomInput } from "@calcom/prisma/client"; + +import { + schemaEventTypeCustomInput, + withValidEventTypeCustomInput, +} from "@lib/validations/eventTypeCustomInput"; type ResponseData = { data?: EventTypeCustomInput; @@ -15,11 +18,13 @@ async function createEventTypeCustomInput(req: NextApiRequest, res: NextApiRespo const { body, method } = req; const safe = schemaEventTypeCustomInput.safeParse(body); if (method === "POST" && safe.success) { - await prisma.eventTypeCustomInput - .create({ data: safe.data }) - .then((data) => res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create eventTypeCustomInput type", error: error })); - // Reject any other HTTP method than POST + await prisma.eventTypeCustomInput + .create({ data: safe.data }) + .then((data) => res.status(201).json({ data })) + .catch((error) => + res.status(400).json({ message: "Could not create eventTypeCustomInput type", error: error }) + ); + // Reject any other HTTP method than POST } else res.status(405).json({ error: "Only POST Method allowed" }); } diff --git a/pages/api/event-types/[id]/delete.ts b/pages/api/event-types/[id]/delete.ts index d94dc611a2..4155c87ce4 100644 --- a/pages/api/event-types/[id]/delete.ts +++ b/pages/api/event-types/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,14 +16,15 @@ export async function deleteEventType(req: NextApiRequest, res: NextApiResponse< const { query, method } = req; const safe = await schemaQueryIdParseInt.safeParse(query); if (method === "DELETE" && safe.success && safe.data) { - const eventType = await prisma.eventType - .delete({ where: { id: safe.data.id } }) + const eventType = await prisma.eventType.delete({ where: { id: safe.data.id } }); // We only remove the eventType type from the database if there's an existing resource. - if (eventType) res.status(200).json({ message: `eventType with id: ${safe.data.id} deleted successfully` }); + if (eventType) + res.status(200).json({ message: `eventType with id: ${safe.data.id} deleted successfully` }); // This catches the error thrown by prisma.eventType.delete() if the resource is not found. - else res.status(400).json({ message: `Resource with id:${safe.data.id} was 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" }); + } else + res.status(405).json({ message: "Only DELETE Method allowed in /availabilities/[id]/delete endpoint" }); } export default withValidQueryIdTransformParseInt(deleteEventType); diff --git a/pages/api/event-types/[id]/edit.ts b/pages/api/event-types/[id]/edit.ts index becd6b5255..6ebe32f026 100644 --- a/pages/api/event-types/[id]/edit.ts +++ b/pages/api/event-types/[id]/edit.ts @@ -1,10 +1,13 @@ -import prisma from "@calcom/prisma"; - -import { EventType } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { EventType } from "@calcom/prisma/client"; + import { schemaEventType, withValidEventType } from "@lib/validations/eventType"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: EventType; @@ -19,18 +22,23 @@ export async function editEventType(req: NextApiRequest, res: NextApiResponse { - res.status(200).json({ data: event }); - }).catch(error => { - res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }) - }); + await prisma.eventType + .update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }) + .then((event) => { + res.status(200).json({ data: event }); + }) + .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 event-types" }); + res.status(405).json({ message: "Only PATCH Method allowed for updating event-types" }); } } diff --git a/pages/api/event-types/[id]/index.ts b/pages/api/event-types/[id]/index.ts index 9b8a159ab3..3e8b642379 100644 --- a/pages/api/event-types/[id]/index.ts +++ b/pages/api/event-types/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { EventType } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { EventType } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: EventType; @@ -26,5 +29,4 @@ export async function eventType(req: NextApiRequest, res: NextApiResponse res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create membership type", error: error })); - // Reject any other HTTP method than POST + await prisma.membership + .create({ data: safe.data }) + .then((data) => res.status(201).json({ data })) + .catch((error) => res.status(400).json({ message: "Could not create membership type", error: error })); + // Reject any other HTTP method than POST } else res.status(405).json({ error: "Only POST Method allowed" }); } diff --git a/pages/api/schedules/[id]/delete.ts b/pages/api/schedules/[id]/delete.ts index 0dcaf7910a..17aba616cf 100644 --- a/pages/api/schedules/[id]/delete.ts +++ b/pages/api/schedules/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,12 +16,11 @@ export async function deleteSchedule(req: NextApiRequest, res: NextApiResponse res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create schedule type", error: error })); - // Reject any other HTTP method than POST + await prisma.schedule + .create({ data: safe.data }) + .then((data) => res.status(201).json({ data })) + .catch((error) => res.status(400).json({ message: "Could not create schedule type", error: error })); + // Reject any other HTTP method than POST } else res.status(405).json({ error: "Only POST Method allowed" }); } diff --git a/pages/api/selected-calendars/[id]/delete.ts b/pages/api/selected-calendars/[id]/delete.ts index 06a0c5a156..a3de0e715b 100644 --- a/pages/api/selected-calendars/[id]/delete.ts +++ b/pages/api/selected-calendars/[id]/delete.ts @@ -1,9 +1,11 @@ -import prisma from "@calcom/prisma"; - import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { message?: string; @@ -14,12 +16,12 @@ export async function deleteSelectedCalendar(req: NextApiRequest, res: NextApiRe const { query, method } = req; const safe = await schemaQueryIdParseInt.safeParse(query); if (method === "DELETE" && safe.success && safe.data) { - const selectedCalendar = await prisma.selectedCalendar - .delete({ where: { id: safe.data.id } }) + const selectedCalendar = await prisma.selectedCalendar.delete({ where: { id: safe.data.id } }); // We only remove the selectedCalendar type from the database if there's an existing resource. - if (selectedCalendar) res.status(200).json({ message: `selectedCalendar with id: ${safe.data.id} deleted successfully` }); + if (selectedCalendar) + res.status(200).json({ message: `selectedCalendar with id: ${safe.data.id} deleted successfully` }); // This catches the error thrown by prisma.selectedCalendar.delete() if the resource is not found. - else res.status(400).json({ message: `Resource with id:${safe.data.id} was 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" }); } diff --git a/pages/api/selected-calendars/[id]/edit.ts b/pages/api/selected-calendars/[id]/edit.ts index 10d5bfde02..0854ffd44f 100644 --- a/pages/api/selected-calendars/[id]/edit.ts +++ b/pages/api/selected-calendars/[id]/edit.ts @@ -1,10 +1,13 @@ -import prisma from "@calcom/prisma"; - -import { SelectedCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { SelectedCalendar } from "@calcom/prisma/client"; + import { schemaSelectedCalendar, withValidSelectedCalendar } from "@lib/validations/selected-calendar"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: SelectedCalendar; @@ -18,15 +21,18 @@ export async function editSelectedCalendar(req: NextApiRequest, res: NextApiResp const safeBody = await schemaSelectedCalendar.safeParse(body); if (method === "PATCH" && safeQuery.success && safeBody.success) { - const data = await prisma.selectedCalendar.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) + const data = await prisma.selectedCalendar.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 }) + 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 selectedCalendars" }); + } else res.status(405).json({ message: "Only PATCH Method allowed for updating selectedCalendars" }); } export default withValidQueryIdTransformParseInt(withValidSelectedCalendar(editSelectedCalendar)); diff --git a/pages/api/selected-calendars/[id]/index.ts b/pages/api/selected-calendars/[id]/index.ts index 6afe9d3135..84a290ae20 100644 --- a/pages/api/selected-calendars/[id]/index.ts +++ b/pages/api/selected-calendars/[id]/index.ts @@ -1,9 +1,12 @@ -import prisma from "@calcom/prisma"; - -import { SelectedCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { SelectedCalendar } from "@calcom/prisma/client"; + +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: SelectedCalendar; @@ -23,5 +26,4 @@ export async function selectedCalendar(req: NextApiRequest, res: NextApiResponse } else res.status(405).json({ message: "Only GET Method allowed" }); } - export default withValidQueryIdTransformParseInt(selectedCalendar); diff --git a/pages/api/selected-calendars/index.ts b/pages/api/selected-calendars/index.ts index d6a29e3dd3..0a4bbd5012 100644 --- a/pages/api/selected-calendars/index.ts +++ b/pages/api/selected-calendars/index.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { SelectedCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { SelectedCalendar } from "@calcom/prisma/client"; + type ResponseData = { data?: SelectedCalendar[]; error?: unknown; diff --git a/pages/api/selected-calendars/new.ts b/pages/api/selected-calendars/new.ts index ee17fcf477..712a936733 100644 --- a/pages/api/selected-calendars/new.ts +++ b/pages/api/selected-calendars/new.ts @@ -1,8 +1,8 @@ -import prisma from "@calcom/prisma"; - -import { SelectedCalendar } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { SelectedCalendar } from "@calcom/prisma/client"; + import { schemaSelectedCalendar, withValidSelectedCalendar } from "@lib/validations/selected-calendar"; type ResponseData = { @@ -15,11 +15,13 @@ async function createSelectedCalendar(req: NextApiRequest, res: NextApiResponse< const { body, method } = req; const safe = schemaSelectedCalendar.safeParse(body); if (method === "POST" && safe.success) { - await prisma.selectedCalendar - .create({ data: safe.data }) - .then((data) => res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create selectedCalendar type", error: error })); - // Reject any other HTTP method than POST + await prisma.selectedCalendar + .create({ data: safe.data }) + .then((data) => res.status(201).json({ data })) + .catch((error) => + res.status(400).json({ message: "Could not create selectedCalendar type", error: error }) + ); + // Reject any other HTTP method than POST } else res.status(405).json({ error: "Only POST Method allowed" }); } diff --git a/pages/api/teams/[id]/delete.ts b/pages/api/teams/[id]/delete.ts index 0593313440..3c88c02d28 100644 --- a/pages/api/teams/[id]/delete.ts +++ b/pages/api/teams/[id]/delete.ts @@ -1,29 +1,31 @@ - import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { - message?: string; - error?: unknown; + message: string; + error?: object; }; export async function deleteTeam(req: NextApiRequest, res: NextApiResponse) { const safe = await schemaQueryIdParseInt.safeParse(req.query); - if (safe.success) { - const data = await prisma.team - .delete({ where: { id: safe.data.id } }) - // We only remove the team type from the database if there's an existing resource. - if (data) res.status(200).json({ message: `Team with id: ${safe.data.id} deleted successfully` }); - // This catches the error thrown by prisma.team.delete() if the resource is not found. - else res.status(400).json({ message: `Team with id: ${safe.data.id} was not able to be processed` }); - } + if (!safe.success) throw new Error("Invalid request query"); + + const data = await prisma.team.delete({ where: { id: safe.data.id } }); + + if (data) res.status(200).json({ message: `Team with id: ${safe.data.id} deleted successfully` }); + else + (error: Error) => + res.status(400).json({ + message: `Team with id: ${safe.data.id} was not able to be processed`, + error, + }); } -export default withMiddleware("deleteOnly", "addRequestId")( - withValidQueryIdTransformParseInt( - deleteTeam - ) -); +export default withMiddleware("HTTP_DELETE", "addRequestId")(withValidQueryIdTransformParseInt(deleteTeam)); diff --git a/pages/api/teams/[id]/edit.ts b/pages/api/teams/[id]/edit.ts index 96e2fa5d3a..f413f7c455 100644 --- a/pages/api/teams/[id]/edit.ts +++ b/pages/api/teams/[id]/edit.ts @@ -1,36 +1,41 @@ -import prisma from "@calcom/prisma"; - -import { Team } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaTeam, withValidTeam } from "@lib/validations/team"; +import prisma from "@calcom/prisma"; +import { Team } from "@calcom/prisma/client"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; +import { schemaTeam, withValidTeam } from "@lib/validations/team"; type ResponseData = { data?: Team; message?: string; - error?: unknown; + error?: object; }; export async function editTeam(req: NextApiRequest, res: NextApiResponse) { - const { query, body, method } = req; - const safeQuery = await schemaQueryIdParseInt.safeParse(query); - const safeBody = await schemaTeam.safeParse(body); + const safeQuery = await schemaQueryIdParseInt.safeParse(req.query); + const safeBody = await schemaTeam.safeParse(req.body); - if (safeQuery.success && safeBody.success) { - const data = await prisma.team.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) - if (data) res.status(200).json({ data }); - else (error: unknown) => res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }) - } + if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request"); + const data = await prisma.team.update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }); + + 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("patchOnly","addRequestId")( - withValidQueryIdTransformParseInt( - withValidTeam( - editTeam) - ) -); +export default withMiddleware( + "HTTP_PATCH", + "addRequestId" +)(withValidQueryIdTransformParseInt(withValidTeam(editTeam))); diff --git a/pages/api/teams/[id]/index.ts b/pages/api/teams/[id]/index.ts index 9868c043fd..aebfbf36a6 100644 --- a/pages/api/teams/[id]/index.ts +++ b/pages/api/teams/[id]/index.ts @@ -1,30 +1,33 @@ -import prisma from "@calcom/prisma"; - -import { Team } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; +import { Team } from "@calcom/prisma/client"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; type ResponseData = { data?: Team; message?: string; - error?: unknown; + error?: object; }; export async function teamById(req: NextApiRequest, res: NextApiResponse) { const safe = await schemaQueryIdParseInt.safeParse(req.query); - if (safe.success) { - const data = await prisma.team.findUnique({ where: { id: safe.data.id } }); + if (!safe.success) throw new Error("Invalid request query"); - if (data) res.status(200).json({ data }); - else res.status(404).json({ message: "Team was not found" }); - } + const data = await prisma.team.findUnique({ where: { id: safe.data.id } }); + + if (data) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: "Team was not found", + error, + }); } - -export default withMiddleware("addRequestId","getOnly")( - withValidQueryIdTransformParseInt( - teamById - ) -); +export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(teamById)); diff --git a/pages/api/teams/index.ts b/pages/api/teams/index.ts index 1fd88d492f..ce090dd0a5 100644 --- a/pages/api/teams/index.ts +++ b/pages/api/teams/index.ts @@ -1,19 +1,26 @@ -import prisma from "@calcom/prisma"; - -import { Team } from "@calcom/prisma/client"; -import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { NextApiRequest, NextApiResponse } from "next"; +import prisma from "@calcom/prisma"; +import { Team } from "@calcom/prisma/client"; + +import { withMiddleware } from "@lib/helpers/withMiddleware"; + type ResponseData = { data?: Team[]; - error?: unknown; + message?: string; + error?: object; }; async function allTeams(req: NextApiRequest, res: NextApiResponse) { const data = await prisma.team.findMany(); if (data) res.status(200).json({ data }); - else res.status(400).json({ error: "No data found" }); + else + (error: Error) => + res.status(400).json({ + message: "No Teams were found", + error, + }); } -export default withMiddleware("addRequestId","getOnly")(allTeams); \ No newline at end of file +export default withMiddleware("HTTP_GET")(allTeams); diff --git a/pages/api/teams/new.ts b/pages/api/teams/new.ts index 7ae4d0034e..a3412a7631 100644 --- a/pages/api/teams/new.ts +++ b/pages/api/teams/new.ts @@ -2,10 +2,10 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; import { Team } from "@calcom/prisma/client"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; import { schemaTeam, withValidTeam } from "@lib/validations/team"; - type ResponseData = { data?: Team; error?: object; @@ -13,16 +13,19 @@ type ResponseData = { async function createTeam(req: NextApiRequest, res: NextApiResponse) { const safe = schemaTeam.safeParse(req.body); - if (safe.success) { - const data = await prisma.team - .create({ data: safe.data }) - if (data) res.status(201).json({ data }) - else (error: unknown) => res.status(400).json({ error: { message: "Could not create team type", error: error } }); - } + if (!safe.success) throw new Error("Invalid request body"); + + const data = await prisma.team.create({ data: safe.data }); + + if (data) res.status(201).json({ data }); + else + (error: Error) => + res.status(400).json({ + error: { + message: "Could not create new team", + error, + }, + }); } -export default withMiddleware("addRequestId","postOnly")( - withValidTeam( - createTeam - ) -); +export default withMiddleware("addRequestId", "HTTP_POST")(withValidTeam(createTeam)); diff --git a/pages/api/users/[id]/delete.ts b/pages/api/users/[id]/delete.ts index 6542b99134..f35f50a36c 100644 --- a/pages/api/users/[id]/delete.ts +++ b/pages/api/users/[id]/delete.ts @@ -1,29 +1,27 @@ - import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import type { BaseResponse } from "@lib/types"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; -type ResponseData = { - message?: string; - error?: unknown; -}; - -export async function deleteUser(req: NextApiRequest, res: NextApiResponse) { +export async function deleteUser(req: NextApiRequest, res: NextApiResponse) { const safe = await schemaQueryIdParseInt.safeParse(req.query); - if (safe.success) { - const data = await prisma.user - .delete({ where: { id: safe.data.id } }) - // We only remove the user type from the database if there's an existing resource. - if (data) res.status(200).json({ message: `User with id: ${safe.data.id} deleted successfully` }); - // This catches the error thrown by prisma.user.delete() if the resource is not found. - else res.status(400).json({ message: `User with id: ${safe.data.id} was not able to be processed` }); - } + if (!safe.success) throw new Error("Invalid request query", safe.error); + + const data = await prisma.user.delete({ where: { id: safe.data.id } }); + + if (data) res.status(200).json({ message: `User with id: ${safe.data.id} deleted successfully` }); + else + (error: Error) => + res.status(400).json({ + message: `User with id: ${safe.data.id} was not able to be processed`, + error, + }); } -export default withMiddleware("deleteOnly", "addRequestId")( - withValidQueryIdTransformParseInt( - deleteUser - ) -); +export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteUser)); diff --git a/pages/api/users/[id]/edit.ts b/pages/api/users/[id]/edit.ts index 3e5425b3d9..bd0ed675de 100644 --- a/pages/api/users/[id]/edit.ts +++ b/pages/api/users/[id]/edit.ts @@ -1,36 +1,33 @@ -import prisma from "@calcom/prisma"; - -import { User } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaUser, withValidUser } from "@lib/validations/user"; +import prisma from "@calcom/prisma"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import type { UserResponse } from "@lib/types"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; +import { schemaUserBodyParams, schemaUserPublic, withValidUser } from "@lib/validations/user"; -type ResponseData = { - data?: User; - message?: string; - error?: unknown; -}; +export async function editUser(req: NextApiRequest, res: NextApiResponse) { + const safeQuery = await schemaQueryIdParseInt.safeParse(req.query); + const safeBody = await schemaUserBodyParams.safeParse(req.body); -export async function editUser(req: NextApiRequest, res: NextApiResponse) { - const { query, body, method } = req; - const safeQuery = await schemaQueryIdParseInt.safeParse(query); - const safeBody = await schemaUser.safeParse(body); + if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request"); + const user = await prisma.user.update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }); + const data = schemaUserPublic.parse(user); - if (safeQuery.success && safeBody.success) { - const data = await prisma.user.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }) - if (data) res.status(200).json({ data }); - else (error: unknown) => res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }) - } + 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("patchOnly","addRequestId")( - withValidQueryIdTransformParseInt( - withValidUser( - editUser) - ) -); +export default withMiddleware("HTTP_PATCH")(withValidQueryIdTransformParseInt(withValidUser(editUser))); diff --git a/pages/api/users/[id]/index.ts b/pages/api/users/[id]/index.ts index 6264acd115..7e7c7cb8ff 100644 --- a/pages/api/users/[id]/index.ts +++ b/pages/api/users/[id]/index.ts @@ -1,30 +1,29 @@ -import prisma from "@calcom/prisma"; - -import { User } from "@calcom/prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; -import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt } from "@lib/validations/shared/queryIdTransformParseInt"; +import prisma from "@calcom/prisma"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { UserResponse } from "@lib/types"; +import { + schemaQueryIdParseInt, + withValidQueryIdTransformParseInt, +} from "@lib/validations/shared/queryIdTransformParseInt"; +import { schemaUserPublic } from "@lib/validations/user"; -type ResponseData = { - data?: User; - message?: string; - error?: unknown; -}; - -export async function userById(req: NextApiRequest, res: NextApiResponse) { +export async function userById(req: NextApiRequest, res: NextApiResponse) { const safe = await schemaQueryIdParseInt.safeParse(req.query); - if (safe.success) { - const data = await prisma.user.findUnique({ where: { id: safe.data.id } }); + if (!safe.success) throw new Error("Invalid request query"); - if (data) res.status(200).json({ data }); - else res.status(404).json({ message: "User was not found" }); - } + const user = await prisma.user.findUnique({ where: { id: safe.data.id } }); + const data = schemaUserPublic.parse(user); + + if (user) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: "User was not found", + error, + }); } - -export default withMiddleware("addRequestId","getOnly")( - withValidQueryIdTransformParseInt( - userById - ) -); +export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(userById)); diff --git a/pages/api/users/index.ts b/pages/api/users/index.ts index ef75e93cc7..365abe4df3 100644 --- a/pages/api/users/index.ts +++ b/pages/api/users/index.ts @@ -1,19 +1,22 @@ -import prisma from "@calcom/prisma"; - -import { User } from "@calcom/prisma/client"; -import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { NextApiRequest, NextApiResponse } from "next"; -type ResponseData = { - data?: User[]; - error?: unknown; -}; +import prisma from "@calcom/prisma"; -async function allUsers(req: NextApiRequest, res: NextApiResponse) { - const data = await prisma.user.findMany(); +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import { UsersResponse } from "@lib/types"; +import { schemaUserPublic } from "@lib/validations/user"; + +async function allUsers(_: NextApiRequest, res: NextApiResponse) { + const users = await prisma.user.findMany(); + const data = users.map((user) => schemaUserPublic.parse(user)); if (data) res.status(200).json({ data }); - else res.status(400).json({ error: "No data found" }); + else + (error: Error) => + res.status(400).json({ + message: "No Users were found", + error, + }); } -export default withMiddleware("addRequestId","getOnly")(allUsers); \ No newline at end of file +export default withMiddleware("HTTP_GET")(allUsers); diff --git a/pages/api/users/new.ts b/pages/api/users/new.ts index 6ce94b5df0..adcf5d7658 100644 --- a/pages/api/users/new.ts +++ b/pages/api/users/new.ts @@ -1,28 +1,25 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { User } from "@calcom/prisma/client"; + import { withMiddleware } from "@lib/helpers/withMiddleware"; -import { schemaUser, withValidUser } from "@lib/validations/user"; +import type { UserResponse } from "@lib/types"; +import { schemaUserBodyParams, schemaUserPublic, withValidUser } from "@lib/validations/user"; +async function createUser(req: NextApiRequest, res: NextApiResponse) { + const safe = schemaUserBodyParams.safeParse(req.body); + if (!safe.success) throw new Error("Invalid request body", safe.error); -type ResponseData = { - data?: User; - error?: object; -}; + const user = await prisma.user.create({ data: safe.data }); + const data = schemaUserPublic.parse(user); -async function createUser(req: NextApiRequest, res: NextApiResponse) { - const safe = schemaUser.safeParse(req.body); - if (safe.success) { - const data = await prisma.user - .create({ data: safe.data }) - if (data) res.status(201).json({ data }) - else (error: unknown) => res.status(400).json({ error: { message: "Could not create user type", error: error } }); - } + if (data) res.status(201).json({ data, message: "User created successfully" }); + else + (error: Error) => + res.status(400).json({ + message: "Could not create new user", + error, + }); } -export default withMiddleware("addRequestId","postOnly")( - withValidUser( - createUser - ) -); +export default withMiddleware("HTTP_POST")(withValidUser(createUser)); diff --git a/prettier.rc.js b/prettier.rc.js new file mode 100644 index 0000000000..aa497c0ac5 --- /dev/null +++ b/prettier.rc.js @@ -0,0 +1,7 @@ +module.exports = { + semi: false, + singleQuote: true, + arrowParens: "avoid", + trailingComma: "none", + endOfLine: "auto", +}; diff --git a/tests/api-keys/[id]/api-key.id.delete.test.ts b/tests/api-keys/[id]/api-key.id.delete.test.ts index fed838a16b..d2abfecb7a 100644 --- a/tests/api-keys/[id]/api-key.id.delete.test.ts +++ b/tests/api-keys/[id]/api-key.id.delete.test.ts @@ -5,7 +5,7 @@ import prisma from "@calcom/prisma"; describe("DELETE /api/api-keys/[id]/delete with valid id as string returns an apiKey", () => { it("returns a message with the specified apiKeys", async () => { - const apiKey = await prisma.apiKey.findFirst() + const apiKey = await prisma.apiKey.findFirst(); const { req, res } = createMocks({ method: "DELETE", query: { @@ -15,7 +15,9 @@ describe("DELETE /api/api-keys/[id]/delete with valid id as string returns an ap // const apiKey = await prisma.apiKey.findUnique({ where: { id: req.query.id} }); await handleDeleteApiKey(req, res); expect(res._getStatusCode()).toBe(204); - expect(JSON.parse(res._getData())).toEqual({message: `api-key with id: ${apiKey?.id} deleted successfully`}); + expect(JSON.parse(res._getData())).toEqual({ + message: `api-key with id: ${apiKey?.id} deleted successfully`, + }); }); }); @@ -56,15 +58,15 @@ describe("DELETE /api/api-keys/[id]/delete an id not present in db like 0, throw expect(res._getStatusCode()).toBe(404); expect(JSON.parse(res._getData())).toStrictEqual({ - "error": { - "clientVersion": "3.10.0", - "code": "P2025", - "meta": { - "cause": "Record to delete does not exist.", - }, - }, - "message": "Resource with id:0 was not found", - }); + error: { + clientVersion: "3.10.0", + code: "P2025", + meta: { + cause: "Record to delete does not exist.", + }, + }, + message: "Resource with id:0 was not found", + }); }); }); @@ -82,5 +84,3 @@ describe("POST /api/api-keys/[id]/delete fails, only DELETE allowed", () => { expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only DELETE Method allowed" }); }); }); - - diff --git a/tests/api-keys/[id]/api-key.id.edit.test.ts b/tests/api-keys/[id]/api-key.id.edit.test.ts index c0d2e3631c..1007181179 100644 --- a/tests/api-keys/[id]/api-key.id.edit.test.ts +++ b/tests/api-keys/[id]/api-key.id.edit.test.ts @@ -2,7 +2,8 @@ import handleapiKeyEdit from "@api/api-keys/[id]/edit"; import { createMocks } from "node-mocks-http"; import prisma from "@calcom/prisma"; -import {stringifyISODate} from "@lib/utils/stringifyISODate"; + +import { stringifyISODate } from "@lib/utils/stringifyISODate"; describe("PATCH /api/api-keys/[id]/edit with valid id and body with note", () => { it("returns a 200 and the updated apiKey note", async () => { @@ -19,7 +20,13 @@ describe("PATCH /api/api-keys/[id]/edit with valid id and body with note", () => await handleapiKeyEdit(req, res); expect(res._getStatusCode()).toBe(200); - expect(JSON.parse(res._getData())).toEqual({ data: {...apiKey, createdAt: stringifyISODate(apiKey?.createdAt), expiresAt: stringifyISODate(apiKey?.expiresAt)} }); + expect(JSON.parse(res._getData())).toEqual({ + data: { + ...apiKey, + createdAt: stringifyISODate(apiKey?.createdAt), + expiresAt: stringifyISODate(apiKey?.expiresAt), + }, + }); }); }); @@ -39,20 +46,22 @@ describe("PATCH /api/api-keys/[id]/edit with invalid id returns 404", () => { expect(res._getStatusCode()).toBe(404); if (apiKey) apiKey.note = "Updated note"; - expect(JSON.parse(res._getData())).toStrictEqual({ "error": { - "clientVersion": "3.10.0", - "code": "P2025", - "meta": { - "cause": "Record to update not found.", - }, + expect(JSON.parse(res._getData())).toStrictEqual({ + error: { + clientVersion: "3.10.0", + code: "P2025", + meta: { + cause: "Record to update not found.", + }, }, - "message": "apiKey with ID cl16zg6860000wwylnsgva00a not found and wasn't updated", }); + message: "apiKey with ID cl16zg6860000wwylnsgva00a not found and wasn't updated", + }); }); }); describe("PATCH /api/api-keys/[id]/edit with valid id and no body returns 200 with an apiKey with no note and default expireAt", () => { it("returns a message with the specified apiKeys", async () => { - const apiKey = await prisma.apiKey.create({data:{} }); + const apiKey = await prisma.apiKey.create({ data: {} }); const { req, res } = createMocks({ method: "PATCH", query: { @@ -63,8 +72,13 @@ describe("PATCH /api/api-keys/[id]/edit with valid id and no body returns 200 wi expect(apiKey?.note).toBeNull(); expect(res._getStatusCode()).toBe(200); - expect(JSON.parse(res._getData())).toEqual({ data: {...apiKey, createdAt: stringifyISODate(apiKey?.createdAt), expiresAt: stringifyISODate(apiKey?.expiresAt)} }); - + expect(JSON.parse(res._getData())).toEqual({ + data: { + ...apiKey, + createdAt: stringifyISODate(apiKey?.createdAt), + expiresAt: stringifyISODate(apiKey?.expiresAt), + }, + }); }); }); @@ -82,8 +96,8 @@ describe("POST /api/api-keys/[id]/edit fails, only PATCH allowed", () => { await handleapiKeyEdit(req, res); expect(res._getStatusCode()).toBe(405); - expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only PATCH Method allowed for updating API keys" }); + expect(JSON.parse(res._getData())).toStrictEqual({ + message: "Only PATCH Method allowed for updating API keys", + }); }); }); - - diff --git a/tests/api-keys/[id]/api-key.id.index.test.ts b/tests/api-keys/[id]/api-key.id.index.test.ts index bdd8996b47..8d3c2655af 100644 --- a/tests/api-keys/[id]/api-key.id.index.test.ts +++ b/tests/api-keys/[id]/api-key.id.index.test.ts @@ -2,7 +2,8 @@ import handleApiKey from "@api/api-keys/[id]"; import { createMocks } from "node-mocks-http"; import prisma from "@calcom/prisma"; -import {stringifyISODate} from "@lib/utils/stringifyISODate"; + +import { stringifyISODate } from "@lib/utils/stringifyISODate"; describe("GET /api/api-keys/[id] with valid id as string returns an apiKey", () => { it("returns a message with the specified apiKeys", async () => { @@ -12,11 +13,17 @@ describe("GET /api/api-keys/[id] with valid id as string returns an apiKey", () id: "cl16zg6860000wwylnsgva00b", }, }); - const apiKey = await prisma.apiKey.findUnique({ where: { id: req.query.id} }); + const apiKey = await prisma.apiKey.findUnique({ where: { id: req.query.id } }); await handleApiKey(req, res); expect(res._getStatusCode()).toBe(200); - expect(JSON.parse(res._getData())).toEqual({ data: {...apiKey, createdAt: stringifyISODate(apiKey?.createdAt), expiresAt: stringifyISODate(apiKey?.expiresAt)} }); + expect(JSON.parse(res._getData())).toEqual({ + data: { + ...apiKey, + createdAt: stringifyISODate(apiKey?.createdAt), + expiresAt: stringifyISODate(apiKey?.expiresAt), + }, + }); }); }); @@ -74,5 +81,3 @@ describe("POST /api/api-keys/[id] fails, only GET allowed", () => { expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only GET Method allowed" }); }); }); - - diff --git a/tests/api-keys/api-key.index.test.ts b/tests/api-keys/api-key.index.test.ts index 87e1bd24b5..957b749b88 100644 --- a/tests/api-keys/api-key.index.test.ts +++ b/tests/api-keys/api-key.index.test.ts @@ -2,7 +2,8 @@ import handleApiKeys from "@api/api-keys"; import { createMocks } from "node-mocks-http"; import prisma from "@calcom/prisma"; -import {stringifyISODate} from "@lib/utils/stringifyISODate"; + +import { stringifyISODate } from "@lib/utils/stringifyISODate"; describe("GET /api/api-keys without any params", () => { it("returns a message with the specified apiKeys", async () => { @@ -14,8 +15,15 @@ describe("GET /api/api-keys without any params", () => { await handleApiKeys(req, res); expect(res._getStatusCode()).toBe(200); - apiKeys = apiKeys.map(apiKey => (apiKey = {...apiKey, createdAt: stringifyISODate(apiKey?.createdAt), expiresAt: stringifyISODate(apiKey?.expiresAt)})); - expect(JSON.parse(res._getData())).toStrictEqual(JSON.parse(JSON.stringify({ data: {...apiKeys} }))); + apiKeys = apiKeys.map( + (apiKey) => + (apiKey = { + ...apiKey, + createdAt: stringifyISODate(apiKey?.createdAt), + expiresAt: stringifyISODate(apiKey?.expiresAt), + }) + ); + expect(JSON.parse(res._getData())).toStrictEqual(JSON.parse(JSON.stringify({ data: { ...apiKeys } }))); }); }); diff --git a/tests/api-keys/api-key.new.test.ts b/tests/api-keys/api-key.new.test.ts index 9507bdbd71..339b4c146b 100644 --- a/tests/api-keys/api-key.new.test.ts +++ b/tests/api-keys/api-key.new.test.ts @@ -28,13 +28,17 @@ describe("POST /api/api-keys/new with a slug param", () => { await handleNewApiKey(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual( - [{"code": "unrecognized_keys", "keys": ["slug"], "message": "Unrecognized key(s) in object: 'slug'", "path": []}] - ); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "unrecognized_keys", + keys: ["slug"], + message: "Unrecognized key(s) in object: 'slug'", + path: [], + }, + ]); }); }); - describe("GET /api/api-keys/new fails, only POST allowed", () => { it("returns a message with the specified apiKeys", async () => { const { req, res } = createMocks({ @@ -47,14 +51,13 @@ describe("GET /api/api-keys/new fails, only POST allowed", () => { }); }); - // FIXME: test 405 when prisma fails look for how to test prisma errors describe("GET /api/api-keys/new fails, only POST allowed", () => { it("returns a message with the specified apiKeys", async () => { const { req, res } = createMocks({ method: "POST", // This POST method is not allowed body: { - nonExistentParam: true + nonExistentParam: true, // note: '123', // slug: 12, }, @@ -62,10 +65,13 @@ describe("GET /api/api-keys/new fails, only POST allowed", () => { await handleNewApiKey(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual([{ - "code": "unrecognized_keys", - "keys": ["nonExistentParam"], - "message": "Unrecognized key(s) in object: 'nonExistentParam'", "path": [] - }]); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "unrecognized_keys", + keys: ["nonExistentParam"], + message: "Unrecognized key(s) in object: 'nonExistentParam'", + path: [], + }, + ]); }); -}); \ No newline at end of file +}); diff --git a/tests/bookings/[id]/booking.id.edit.test.ts b/tests/bookings/[id]/booking.id.edit.test.ts index 5b7c1ec73f..8bf32eb0e5 100644 --- a/tests/bookings/[id]/booking.id.edit.test.ts +++ b/tests/bookings/[id]/booking.id.edit.test.ts @@ -43,14 +43,16 @@ describe("PATCH /api/bookings/[id]/edit with invalid id returns 404", () => { expect(res._getStatusCode()).toBe(404); if (booking) booking.title = "Updated title"; - expect(JSON.parse(res._getData())).toStrictEqual({ "error": { - "clientVersion": "3.10.0", - "code": "P2025", - "meta": { - "cause": "Record to update not found.", - }, + expect(JSON.parse(res._getData())).toStrictEqual({ + error: { + clientVersion: "3.10.0", + code: "P2025", + meta: { + cause: "Record to update not found.", + }, }, - "message": "Event type with ID 0 not found and wasn't updated", }); + message: "Event type with ID 0 not found and wasn't updated", + }); }); }); @@ -65,7 +67,29 @@ describe("PATCH /api/bookings/[id]/edit with valid id and no body returns 400 er await handleBookingEdit(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual([{"code": "invalid_type", "expected": "string", "message": "Required", "path": ["title"], "received": "undefined"}, {"code": "invalid_type", "expected": "string", "message": "Required", "path": ["slug"], "received": "undefined"}, {"code": "invalid_type", "expected": "number", "message": "Required", "path": ["length"], "received": "undefined"}]); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["title"], + received: "undefined", + }, + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["slug"], + received: "undefined", + }, + { + code: "invalid_type", + expected: "number", + message: "Required", + path: ["length"], + received: "undefined", + }, + ]); }); }); @@ -85,8 +109,8 @@ describe("POST /api/bookings/[id]/edit fails, only PATCH allowed", () => { await handleBookingEdit(req, res); expect(res._getStatusCode()).toBe(405); - expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only PATCH Method allowed for updating bookings" }); + expect(JSON.parse(res._getData())).toStrictEqual({ + message: "Only PATCH Method allowed for updating bookings", + }); }); }); - - diff --git a/tests/bookings/[id]/booking.id.index.test.ts b/tests/bookings/[id]/booking.id.index.test.ts index d4edede123..4a2ff0ca0c 100644 --- a/tests/bookings/[id]/booking.id.index.test.ts +++ b/tests/bookings/[id]/booking.id.index.test.ts @@ -2,6 +2,7 @@ import handleBooking from "@api/bookings/[id]"; import { createMocks } from "node-mocks-http"; import prisma from "@calcom/prisma"; + import { stringifyISODate } from "@lib/utils/stringifyISODate"; describe("GET /api/bookings/[id] with valid id as string returns an booking", () => { @@ -21,8 +22,8 @@ describe("GET /api/bookings/[id] with valid id as string returns an booking", () ...booking, createdAt: stringifyISODate(booking?.createdAt), startTime: stringifyISODate(booking?.startTime), - endTime: stringifyISODate(booking?.endTime) - } + endTime: stringifyISODate(booking?.endTime), + }, }); }); }); @@ -81,5 +82,3 @@ describe("POST /api/bookings/[id] fails, only GET allowed", () => { expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only GET Method allowed" }); }); }); - - diff --git a/tests/bookings/booking.index.test.ts b/tests/bookings/booking.index.test.ts index 87e1bd24b5..957b749b88 100644 --- a/tests/bookings/booking.index.test.ts +++ b/tests/bookings/booking.index.test.ts @@ -2,7 +2,8 @@ import handleApiKeys from "@api/api-keys"; import { createMocks } from "node-mocks-http"; import prisma from "@calcom/prisma"; -import {stringifyISODate} from "@lib/utils/stringifyISODate"; + +import { stringifyISODate } from "@lib/utils/stringifyISODate"; describe("GET /api/api-keys without any params", () => { it("returns a message with the specified apiKeys", async () => { @@ -14,8 +15,15 @@ describe("GET /api/api-keys without any params", () => { await handleApiKeys(req, res); expect(res._getStatusCode()).toBe(200); - apiKeys = apiKeys.map(apiKey => (apiKey = {...apiKey, createdAt: stringifyISODate(apiKey?.createdAt), expiresAt: stringifyISODate(apiKey?.expiresAt)})); - expect(JSON.parse(res._getData())).toStrictEqual(JSON.parse(JSON.stringify({ data: {...apiKeys} }))); + apiKeys = apiKeys.map( + (apiKey) => + (apiKey = { + ...apiKey, + createdAt: stringifyISODate(apiKey?.createdAt), + expiresAt: stringifyISODate(apiKey?.expiresAt), + }) + ); + expect(JSON.parse(res._getData())).toStrictEqual(JSON.parse(JSON.stringify({ data: { ...apiKeys } }))); }); }); diff --git a/tests/bookings/booking.new.test.ts b/tests/bookings/booking.new.test.ts index 9507bdbd71..339b4c146b 100644 --- a/tests/bookings/booking.new.test.ts +++ b/tests/bookings/booking.new.test.ts @@ -28,13 +28,17 @@ describe("POST /api/api-keys/new with a slug param", () => { await handleNewApiKey(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual( - [{"code": "unrecognized_keys", "keys": ["slug"], "message": "Unrecognized key(s) in object: 'slug'", "path": []}] - ); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "unrecognized_keys", + keys: ["slug"], + message: "Unrecognized key(s) in object: 'slug'", + path: [], + }, + ]); }); }); - describe("GET /api/api-keys/new fails, only POST allowed", () => { it("returns a message with the specified apiKeys", async () => { const { req, res } = createMocks({ @@ -47,14 +51,13 @@ describe("GET /api/api-keys/new fails, only POST allowed", () => { }); }); - // FIXME: test 405 when prisma fails look for how to test prisma errors describe("GET /api/api-keys/new fails, only POST allowed", () => { it("returns a message with the specified apiKeys", async () => { const { req, res } = createMocks({ method: "POST", // This POST method is not allowed body: { - nonExistentParam: true + nonExistentParam: true, // note: '123', // slug: 12, }, @@ -62,10 +65,13 @@ describe("GET /api/api-keys/new fails, only POST allowed", () => { await handleNewApiKey(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual([{ - "code": "unrecognized_keys", - "keys": ["nonExistentParam"], - "message": "Unrecognized key(s) in object: 'nonExistentParam'", "path": [] - }]); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "unrecognized_keys", + keys: ["nonExistentParam"], + message: "Unrecognized key(s) in object: 'nonExistentParam'", + path: [], + }, + ]); }); -}); \ No newline at end of file +}); diff --git a/tests/event-types/[id]/event-type.id.edit.test.ts b/tests/event-types/[id]/event-type.id.edit.test.ts index b3cd506a37..e88bcb9b49 100644 --- a/tests/event-types/[id]/event-type.id.edit.test.ts +++ b/tests/event-types/[id]/event-type.id.edit.test.ts @@ -43,14 +43,16 @@ describe("PATCH /api/event-types/[id]/edit with invalid id returns 404", () => { expect(res._getStatusCode()).toBe(404); if (event) event.title = "Updated title"; - expect(JSON.parse(res._getData())).toStrictEqual({ "error": { - "clientVersion": "3.10.0", - "code": "P2025", - "meta": { - "cause": "Record to update not found.", - }, + expect(JSON.parse(res._getData())).toStrictEqual({ + error: { + clientVersion: "3.10.0", + code: "P2025", + meta: { + cause: "Record to update not found.", + }, }, - "message": "Event type with ID 0 not found and wasn't updated", }); + message: "Event type with ID 0 not found and wasn't updated", + }); }); }); @@ -65,7 +67,29 @@ describe("PATCH /api/event-types/[id]/edit with valid id and no body returns 400 await handleEventTypeEdit(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual([{"code": "invalid_type", "expected": "string", "message": "Required", "path": ["title"], "received": "undefined"}, {"code": "invalid_type", "expected": "string", "message": "Required", "path": ["slug"], "received": "undefined"}, {"code": "invalid_type", "expected": "number", "message": "Required", "path": ["length"], "received": "undefined"}]); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["title"], + received: "undefined", + }, + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["slug"], + received: "undefined", + }, + { + code: "invalid_type", + expected: "number", + message: "Required", + path: ["length"], + received: "undefined", + }, + ]); }); }); @@ -85,8 +109,8 @@ describe("POST /api/event-types/[id]/edit fails, only PATCH allowed", () => { await handleEventTypeEdit(req, res); expect(res._getStatusCode()).toBe(405); - expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only PATCH Method allowed for updating event-types" }); + expect(JSON.parse(res._getData())).toStrictEqual({ + message: "Only PATCH Method allowed for updating event-types", + }); }); }); - - diff --git a/tests/event-types/[id]/event-type.id.index.test.ts b/tests/event-types/[id]/event-type.id.index.test.ts index 46b4e0af21..bb54d5963f 100644 --- a/tests/event-types/[id]/event-type.id.index.test.ts +++ b/tests/event-types/[id]/event-type.id.index.test.ts @@ -73,5 +73,3 @@ describe("POST /api/event-types/[id] fails, only GET allowed", () => { expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only GET Method allowed" }); }); }); - - diff --git a/tests/event-types/event-type.index.test.ts b/tests/event-types/event-type.index.test.ts index 668d88a9d7..7a63a59a5d 100644 --- a/tests/event-types/event-type.index.test.ts +++ b/tests/event-types/event-type.index.test.ts @@ -2,6 +2,7 @@ import handleApiKeys from "@api/event-types"; import { createMocks } from "node-mocks-http"; import prisma from "@calcom/prisma"; + // import {stringifyISODate} from "@lib/utils/stringifyISODate"; describe("GET /api/event-types without any params", () => { @@ -15,7 +16,7 @@ describe("GET /api/event-types without any params", () => { expect(res._getStatusCode()).toBe(200); // eventTypes = eventTypes.map(eventType => (eventType = {...eventType, createdAt: stringifyISODate(eventType?.createdAt), expiresAt: stringifyISODate(eventType?.expiresAt)})); - expect(JSON.parse(res._getData())).toStrictEqual(JSON.parse(JSON.stringify({ data: {...eventTypes} }))); + expect(JSON.parse(res._getData())).toStrictEqual(JSON.parse(JSON.stringify({ data: { ...eventTypes } }))); }); }); diff --git a/tests/event-types/event-type.new.test.ts b/tests/event-types/event-type.new.test.ts index 01dab107a9..a79209ec03 100644 --- a/tests/event-types/event-type.new.test.ts +++ b/tests/event-types/event-type.new.test.ts @@ -16,7 +16,6 @@ describe("POST /api/api-keys/new with a note", () => { }); }); - describe("POST /api/api-keys/new with a slug param", () => { it("returns error 400, and the details about invalid slug body param", async () => { const { req, res } = createMocks({ @@ -29,13 +28,17 @@ describe("POST /api/api-keys/new with a slug param", () => { await handleNewApiKey(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual( - [{"code": "unrecognized_keys", "keys": ["slug"], "message": "Unrecognized key(s) in object: 'slug'", "path": []}] - ); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "unrecognized_keys", + keys: ["slug"], + message: "Unrecognized key(s) in object: 'slug'", + path: [], + }, + ]); }); }); - describe("GET /api/api-keys/new fails, only POST allowed", () => { it("returns a message with the specified apiKeys", async () => { const { req, res } = createMocks({ @@ -48,7 +51,6 @@ describe("GET /api/api-keys/new fails, only POST allowed", () => { }); }); - // FIXME: test 405 when prisma fails look for how to test prisma errors // describe("GET /api/api-keys/new fails, only POST allowed", () => { // it("returns a message with the specified apiKeys", async () => { @@ -65,4 +67,4 @@ describe("GET /api/api-keys/new fails, only POST allowed", () => { // expect(res._getStatusCode()).toBe(400); // expect(JSON.parse(res._getData())).toStrictEqual({ error: "Only POST Method allowed" }); // }); -// }); \ No newline at end of file +// }); diff --git a/tests/teams/[id]/team.id.edit.test.ts b/tests/teams/[id]/team.id.edit.test.ts index 43df801088..101deaa06e 100644 --- a/tests/teams/[id]/team.id.edit.test.ts +++ b/tests/teams/[id]/team.id.edit.test.ts @@ -40,14 +40,16 @@ describe("PATCH /api/teams/[id]/edit with invalid id returns 404", () => { await handleTeamEdit(req, res); expect(res._getStatusCode()).toBe(404); - expect(JSON.parse(res._getData())).toStrictEqual({ "error": { - "clientVersion": "3.10.0", - "code": "P2025", - "meta": { - "cause": "Record to update not found.", - }, + expect(JSON.parse(res._getData())).toStrictEqual({ + error: { + clientVersion: "3.10.0", + code: "P2025", + meta: { + cause: "Record to update not found.", + }, }, - "message": "Event type with ID 0 not found and wasn't updated", }); + message: "Event type with ID 0 not found and wasn't updated", + }); }); }); @@ -64,7 +66,22 @@ describe("PATCH /api/teams/[id]/edit with valid id and no body returns 400 error expect(res._getStatusCode()).toBe(400); // Ugly parsing of zod validation errors, not for final production but works for testing - expect(JSON.parse(res._getData())).toStrictEqual([{"code": "invalid_type", "expected": "string", "message": "Required", "path": ["slug"], "received": "undefined"}, {"code": "invalid_type", "expected": "string", "message": "Required", "path": ["name"], "received": "undefined"}]); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["slug"], + received: "undefined", + }, + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["name"], + received: "undefined", + }, + ]); }); }); @@ -83,8 +100,8 @@ describe("POST /api/teams/[id]/edit fails, only PATCH allowed", () => { await handleTeamEdit(req, res); expect(res._getStatusCode()).toBe(405); - expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only PATCH Method allowed for updating teams" }); + expect(JSON.parse(res._getData())).toStrictEqual({ + message: "Only PATCH Method allowed for updating teams", + }); }); }); - - diff --git a/tests/teams/[id]/team.id.index.test.ts b/tests/teams/[id]/team.id.index.test.ts index 1f0aec27f9..016f7ec604 100644 --- a/tests/teams/[id]/team.id.index.test.ts +++ b/tests/teams/[id]/team.id.index.test.ts @@ -73,5 +73,3 @@ describe("POST /api/teams/[id] fails, only GET allowed", () => { expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only GET Method allowed" }); }); }); - - diff --git a/tests/users/[id]/user.id.edit.test.ts b/tests/users/[id]/user.id.edit.test.ts index b3cd506a37..e88bcb9b49 100644 --- a/tests/users/[id]/user.id.edit.test.ts +++ b/tests/users/[id]/user.id.edit.test.ts @@ -43,14 +43,16 @@ describe("PATCH /api/event-types/[id]/edit with invalid id returns 404", () => { expect(res._getStatusCode()).toBe(404); if (event) event.title = "Updated title"; - expect(JSON.parse(res._getData())).toStrictEqual({ "error": { - "clientVersion": "3.10.0", - "code": "P2025", - "meta": { - "cause": "Record to update not found.", - }, + expect(JSON.parse(res._getData())).toStrictEqual({ + error: { + clientVersion: "3.10.0", + code: "P2025", + meta: { + cause: "Record to update not found.", + }, }, - "message": "Event type with ID 0 not found and wasn't updated", }); + message: "Event type with ID 0 not found and wasn't updated", + }); }); }); @@ -65,7 +67,29 @@ describe("PATCH /api/event-types/[id]/edit with valid id and no body returns 400 await handleEventTypeEdit(req, res); expect(res._getStatusCode()).toBe(400); - expect(JSON.parse(res._getData())).toStrictEqual([{"code": "invalid_type", "expected": "string", "message": "Required", "path": ["title"], "received": "undefined"}, {"code": "invalid_type", "expected": "string", "message": "Required", "path": ["slug"], "received": "undefined"}, {"code": "invalid_type", "expected": "number", "message": "Required", "path": ["length"], "received": "undefined"}]); + expect(JSON.parse(res._getData())).toStrictEqual([ + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["title"], + received: "undefined", + }, + { + code: "invalid_type", + expected: "string", + message: "Required", + path: ["slug"], + received: "undefined", + }, + { + code: "invalid_type", + expected: "number", + message: "Required", + path: ["length"], + received: "undefined", + }, + ]); }); }); @@ -85,8 +109,8 @@ describe("POST /api/event-types/[id]/edit fails, only PATCH allowed", () => { await handleEventTypeEdit(req, res); expect(res._getStatusCode()).toBe(405); - expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only PATCH Method allowed for updating event-types" }); + expect(JSON.parse(res._getData())).toStrictEqual({ + message: "Only PATCH Method allowed for updating event-types", + }); }); }); - - diff --git a/tests/users/[id]/user.id.index.test.ts b/tests/users/[id]/user.id.index.test.ts index 512677981a..bf79c38143 100644 --- a/tests/users/[id]/user.id.index.test.ts +++ b/tests/users/[id]/user.id.index.test.ts @@ -2,6 +2,7 @@ import handleUser from "@api/users/[id]"; import { createMocks } from "node-mocks-http"; import prisma from "@calcom/prisma"; + import { stringifyISODate } from "@lib/utils/stringifyISODate"; describe("GET /api/users/[id] with valid id as string returns an user-type", () => { @@ -16,7 +17,13 @@ describe("GET /api/users/[id] with valid id as string returns an user-type", () await handleUser(req, res); expect(res._getStatusCode()).toBe(200); - expect(JSON.parse(res._getData())).toEqual({ data: {...user, createdDate: stringifyISODate(user?.createdDate), emailVerified: stringifyISODate(user?.emailVerified)} }); + expect(JSON.parse(res._getData())).toEqual({ + data: { + ...user, + createdDate: stringifyISODate(user?.createdDate), + emailVerified: stringifyISODate(user?.emailVerified), + }, + }); }); }); @@ -74,5 +81,3 @@ describe("POST /api/users/[id] fails, only GET allowed", () => { expect(JSON.parse(res._getData())).toStrictEqual({ message: "Only GET Method allowed" }); }); }); - - diff --git a/tsconfig.json b/tsconfig.json index 93bbf8be81..7859f5e38e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,12 @@ { "extends": "@calcom/tsconfig/base.json", - "exclude": [ - "node_modules" - ], + "exclude": ["node_modules"], "compilerOptions": { "strictNullChecks": true, "baseUrl": ".", - + "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "noEmit": true, "incremental": true, @@ -20,11 +14,10 @@ "resolveJsonModule": true, "jsx": "preserve", "paths": { - "@api/*": ["pages/api/*"], - "@lib/*": ["lib/*"], - "@/*": ["*"] - -}, + "@api/*": ["pages/api/*"], + "@lib/*": ["lib/*"], + "@/*": ["*"] + } }, "include": ["./**/*.ts"] }