feat: inherit all validations from auto-generated zod

pull/9078/head
Agusti Fernandez Pardo 2022-03-30 17:37:51 +02:00
parent 064c39b7f6
commit 9aa4b0e30d
19 changed files with 372 additions and 224 deletions

View File

@ -1,4 +1,20 @@
import { User, ApiKey, Team, SelectedCalendar } from "@calcom/prisma/client"; import {
User,
ApiKey,
Team,
SelectedCalendar,
EventType,
Attendee,
Availability,
BookingReference,
Booking,
DailyEventReference,
Webhook,
DestinationCalendar,
Membership,
Payment,
Schedule,
} from "@calcom/prisma/client";
// Base response, used for all responses // Base response, used for all responses
export type BaseResponse = { export type BaseResponse = {
@ -21,7 +37,7 @@ export type ApiKeysResponse = BaseResponse & {
data?: Partial<ApiKey>[]; data?: Partial<ApiKey>[];
}; };
// API Key // Team
export type TeamResponse = BaseResponse & { export type TeamResponse = BaseResponse & {
data?: Partial<Team>; data?: Partial<Team>;
}; };
@ -29,10 +45,106 @@ export type TeamsResponse = BaseResponse & {
data?: Partial<Team>[]; data?: Partial<Team>[];
}; };
// API Key // SelectedCalendar
export type SelectedCalendarResponse = BaseResponse & { export type SelectedCalendarResponse = BaseResponse & {
data?: Partial<SelectedCalendar>; data?: Partial<SelectedCalendar>;
}; };
export type SelectedCalendarsResponse = BaseResponse & { export type SelectedCalendarsResponse = BaseResponse & {
data?: Partial<SelectedCalendar>[]; data?: Partial<SelectedCalendar>[];
}; };
// Attendee
export type AttendeeResponse = BaseResponse & {
data?: Partial<Attendee>;
};
export type AttendeesResponse = BaseResponse & {
data?: Partial<Attendee>[];
};
// Availability
export type AvailabilityResponse = BaseResponse & {
data?: Partial<Availability>;
};
export type AvailabilitysResponse = BaseResponse & {
data?: Partial<Availability>[];
};
// BookingReference
export type BookingReferenceResponse = BaseResponse & {
data?: Partial<BookingReference>;
};
export type BookingReferencesResponse = BaseResponse & {
data?: Partial<BookingReference>[];
};
// Booking
export type BookingResponse = BaseResponse & {
data?: Partial<Booking>;
};
export type BookingsResponse = BaseResponse & {
data?: Partial<Booking>[];
};
// Credential
export type CredentialResponse = BaseResponse & {
data?: Partial<Credential>;
};
export type CredentialsResponse = BaseResponse & {
data?: Partial<Credential>[];
};
// DailyEventReference
export type DailyEventReferenceResponse = BaseResponse & {
data?: Partial<DailyEventReference>;
};
export type DailyEventReferencesResponse = BaseResponse & {
data?: Partial<DailyEventReference>[];
};
// DestinationCalendar
export type DestinationCalendarResponse = BaseResponse & {
data?: Partial<DestinationCalendar>;
};
export type DestinationCalendarsResponse = BaseResponse & {
data?: Partial<DestinationCalendar>[];
};
// Membership
export type MembershipResponse = BaseResponse & {
data?: Partial<Membership>;
};
export type MembershipsResponse = BaseResponse & {
data?: Partial<Membership>[];
};
// EventType
export type EventTypeResponse = BaseResponse & {
data?: Partial<EventType>;
};
export type EventTypesResponse = BaseResponse & {
data?: Partial<EventType>[];
};
// Payment
export type PaymentResponse = BaseResponse & {
data?: Partial<Payment>;
};
export type PaymentsResponse = BaseResponse & {
data?: Partial<Payment>[];
};
// Schedule
export type ScheduleResponse = BaseResponse & {
data?: Partial<Schedule>;
};
export type SchedulesResponse = BaseResponse & {
data?: Partial<Schedule>[];
};
// Webhook
export type WebhookResponse = BaseResponse & {
data?: Partial<Webhook>;
};
export type WebhooksResponse = BaseResponse & {
data?: Partial<Webhook>[];
};

View File

@ -1,20 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaAttendee = z import { _AttendeeModel as Attendee } from "@calcom/prisma/zod";
.object({
id: z.number(), export const schemaAttendeeBodyParams = Attendee.omit({ id: true });
email: z.string().min(3),
name: z.string().min(3).email(), export const schemaAttendeePublic = Attendee.omit({});
timeZone: z.string().default("Europe/London"),
locale: z.string().optional(), export const withValidAttendee = withValidation({
bookingId: z.number(), schema: schemaAttendeeBodyParams,
})
.strict();
const withValidAttendee = withValidation({
schema: schemaAttendee,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaAttendee, withValidAttendee };

View File

@ -1,23 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaAvailability = z import { _AvailabilityModel as Availability } from "@calcom/prisma/zod";
.object({
id: z.number(),
userId: z.number(),
eventTypeId: z.number(),
scheduleId: z.number(),
days: z.array(z.number()), export const schemaAvailabilityBodyParams = Availability.omit({ id: true });
date: z.date().or(z.string()),
startTime: z.string(), export const schemaAvailabilityPublic = Availability.omit({});
endTime: z.string(),
}) export const withValidAvailability = withValidation({
.strict(); schema: schemaAvailabilityBodyParams,
const withValidAvailability = withValidation({
schema: schemaAvailability,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaAvailability, withValidAvailability };

View File

@ -1,11 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaBookingReference = z.object({}).strict(); import { _BookingReferenceModel as BookingReference } from "@calcom/prisma/zod";
const withValidBookingReference = withValidation({
schema: schemaBookingReference, export const schemaBookingReferenceBodyParams = BookingReference.omit({ id: true });
export const schemaBookingReferencePublic = BookingReference.omit({});
export const withValidBookingReference = withValidation({
schema: schemaBookingReferenceBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaBookingReference, withValidBookingReference };

View File

@ -1,25 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaBooking = z import { _BookingModel as Booking } from "@calcom/prisma/zod";
.object({
uid: z.string().min(3), export const schemaBookingBodyParams = Booking.omit({ id: true });
title: z.string().min(3),
description: z.string().min(3).optional(), export const schemaBookingPublic = Booking.omit({});
startTime: z.date().or(z.string()),
endTime: z.date(), export const withValidBooking = withValidation({
location: z.string().min(3).optional(), schema: schemaBookingBodyParams,
createdAt: z.date().or(z.string()),
updatedAt: z.date().or(z.string()),
confirmed: z.boolean().default(true),
rejected: z.boolean().default(false),
paid: z.boolean().default(false),
})
.strict();
const withValidBooking = withValidation({
schema: schemaBooking,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaBooking, withValidBooking };

View File

@ -1,11 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaCredential = z.object({}).strict(); import { _CredentialModel as Credential } from "@calcom/prisma/zod";
const withValidCredential = withValidation({
schema: schemaCredential, export const schemaCredentialBodyParams = Credential.omit({ id: true });
export const schemaCredentialPublic = Credential.omit({});
export const withValidCredential = withValidation({
schema: schemaCredentialBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaCredential, withValidCredential };

View File

@ -1,11 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaDailyEventReference = z.object({}).strict(); import { _DailyEventReferenceModel as DailyEventReference } from "@calcom/prisma/zod";
const withValidDailyEventReference = withValidation({
schema: schemaDailyEventReference, export const schemaDailyEventReferenceBodyParams = DailyEventReference.omit({ id: true });
export const schemaDailyEventReferencePublic = DailyEventReference.omit({});
export const withValidDailyEventReference = withValidation({
schema: schemaDailyEventReferenceBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaDailyEventReference, withValidDailyEventReference };

View File

@ -1,11 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaDestinationCalendar = z.object({}).strict(); import { _DestinationCalendarModel as DestinationCalendar } from "@calcom/prisma/zod";
const withValidDestinationCalendar = withValidation({
schema: schemaDestinationCalendar, export const schemaDestinationCalendarBodyParams = DestinationCalendar.omit({ id: true });
export const schemaDestinationCalendarPublic = DestinationCalendar.omit({});
export const withValidDestinationCalendar = withValidation({
schema: schemaDestinationCalendarBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaDestinationCalendar, withValidDestinationCalendar };

View File

@ -1,18 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaEventType = z import { _EventTypeModel as EventType } from "@calcom/prisma/zod";
.object({
title: z.string().min(3), export const schemaEventTypeBodyParams = EventType.omit({ id: true });
slug: z.string().min(3),
length: z.number().min(1).max(1440), // max is a full day. export const schemaEventTypePublic = EventType.omit({});
description: z.string().min(3).optional(),
}) export const withValidEventType = withValidation({
.strict(); schema: schemaEventTypeBodyParams,
const withValidEventType = withValidation({
schema: schemaEventType,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaEventType, withValidEventType };

View File

@ -1,11 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaMembership = z.object({}).strict(); import { _MembershipModel as Membership } from "@calcom/prisma/zod";
const withValidMembership = withValidation({
schema: schemaMembership, export const schemaMembershipBodyParams = Membership.omit({});
export const schemaMembershipPublic = Membership.omit({});
export const withValidMembership = withValidation({
schema: schemaMembershipBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaMembership, withValidMembership };

View File

@ -1,11 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaPayment = z.object({}).strict(); import { _PaymentModel as Payment } from "@calcom/prisma/zod";
const withValidPayment = withValidation({
schema: schemaPayment, export const schemaPaymentBodyParams = Payment.omit({ id: true });
export const schemaPaymentPublic = Payment.omit({});
export const withValidPayment = withValidation({
schema: schemaPaymentBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaPayment, withValidPayment };

View File

@ -1,11 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaSchedule = z.object({}).strict(); import { _ScheduleModel as Schedule } from "@calcom/prisma/zod";
const withValidSchedule = withValidation({
schema: schemaSchedule, export const schemaScheduleBodyParams = Schedule.omit({ id: true });
export const schemaSchedulePublic = Schedule.omit({});
export const withValidSchedule = withValidation({
schema: schemaScheduleBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaSchedule, withValidSchedule };

View File

@ -1,12 +1,13 @@
import { withValidation } from "next-validations"; import { withValidation } from "next-validations";
import { z } from "zod";
const schemaWebhook = z.object({}).strict(); import { _WebhookModel as Webhook } from "@calcom/prisma/zod";
const withValidWebhook = withValidation({ export const schemaWebhookBodyParams = Webhook.omit({ id: true });
schema: schemaWebhook,
export const schemaWebhookPublic = Webhook.omit({});
export const withValidWebhook = withValidation({
schema: schemaWebhookBodyParams,
type: "Zod", type: "Zod",
mode: "body", mode: "body",
}); });
export { schemaWebhook, withValidWebhook };

View File

@ -1,11 +1,10 @@
// import { NextApiResponse } from "next";
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
// Not much useful yet as prisma.client can't be used in the middlewares (client is not available) // 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, // 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. // but we could also check if the apiKey is valid if we had prisma here.
export default async function requireApiKeyAsQueryParams({ nextUrl }: NextRequest, res: NextResponse) { export default async function requireApiKeyAsQueryParams({ nextUrl }: NextRequest) {
const response = NextResponse.next(); const response = NextResponse.next();
const apiKey = nextUrl.searchParams.get("apiKey"); const apiKey = nextUrl.searchParams.get("apiKey");

View File

@ -2,29 +2,40 @@ import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { BaseResponse } from "@lib/types";
import { import {
schemaQueryIdParseInt, schemaQueryIdParseInt,
withValidQueryIdTransformParseInt, withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt"; } from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = { /**
message?: string; * @swagger
error?: unknown; * /api/eventTypes/:id/delete:
}; * delete:
* description: Remove an existing eventType
* responses:
* 201:
* description: OK, eventType removed successfuly
* model: EventType
* 400:
* description: Bad request. EventType id is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function deleteEventType(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query", safe.error);
export async function deleteEventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) { const data = await prisma.eventType.delete({ where: { id: safe.data.id } });
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query); if (data) res.status(200).json({ message: `EventType with id: ${safe.data.id} deleted successfully` });
if (method === "DELETE" && safe.success && safe.data) { else
const eventType = await prisma.eventType.delete({ where: { id: safe.data.id } }); (error: Error) =>
// We only remove the eventType type from the database if there's an existing resource. res.status(400).json({
if (eventType) message: `EventType with id: ${safe.data.id} was not able to be processed`,
res.status(200).json({ message: `eventType with id: ${safe.data.id} deleted successfully` }); error,
// 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` });
// Reject any other HTTP method than POST
} else
res.status(405).json({ message: "Only DELETE Method allowed in /availabilities/[id]/delete endpoint" });
} }
export default withValidQueryIdTransformParseInt(deleteEventType); export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteEventType));

View File

@ -1,45 +1,53 @@
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { EventType } from "@calcom/prisma/client";
import { schemaEventType, withValidEventType } from "@lib/validations/eventType"; import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { EventTypeResponse } from "@lib/types";
import {
schemaEventTypeBodyParams,
schemaEventTypePublic,
withValidEventType,
} from "@lib/validations/eventType";
import { import {
schemaQueryIdParseInt, schemaQueryIdParseInt,
withValidQueryIdTransformParseInt, withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt"; } from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = { /**
data?: EventType; * @swagger
message?: string; * /api/eventTypes/:id/edit:
error?: unknown; * patch:
}; * description: Edits an existing eventType
* responses:
* 201:
* description: OK, eventType edited successfuly
* model: EventType
* 400:
* description: Bad request. EventType body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function editEventType(req: NextApiRequest, res: NextApiResponse<EventTypeResponse>) {
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
const safeBody = await schemaEventTypeBodyParams.safeParse(req.body);
export async function editEventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) { if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
const { query, body, method } = req; const eventType = await prisma.eventType.update({
const safeQuery = await schemaQueryIdParseInt.safeParse(query); where: { id: safeQuery.data.id },
const safeBody = await schemaEventType.safeParse(body); data: safeBody.data,
});
const data = schemaEventTypePublic.parse(eventType);
if (method === "PATCH") { if (data) res.status(200).json({ data });
if (safeQuery.success && safeBody.success) { else
await prisma.eventType (error: Error) =>
.update({ res.status(404).json({
where: { id: safeQuery.data.id }, message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`,
data: safeBody.data, error,
}) });
.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" });
}
} }
export default withValidQueryIdTransformParseInt(withValidEventType(editEventType)); export default withMiddleware("HTTP_PATCH")(
withValidQueryIdTransformParseInt(withValidEventType(editEventType))
);

View File

@ -1,32 +1,42 @@
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { EventType } from "@calcom/prisma/client";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { EventTypeResponse } from "@lib/types";
import { schemaEventTypePublic } from "@lib/validations/eventType";
import { import {
schemaQueryIdParseInt, schemaQueryIdParseInt,
withValidQueryIdTransformParseInt, withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt"; } from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = { /**
data?: EventType; * @swagger
message?: string; * /api/eventTypes/:id:
error?: unknown; * get:
}; * description: find eventType by ID
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: EventType was not found
*/
export async function eventTypeById(req: NextApiRequest, res: NextApiResponse<EventTypeResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query");
export async function eventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) { const eventType = await prisma.eventType.findUnique({ where: { id: safe.data.id } });
const { query, method } = req; const data = schemaEventTypePublic.parse(eventType);
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "GET" && safe.success) { if (eventType) res.status(200).json({ data });
const event = await prisma.eventType.findUnique({ where: { id: safe.data.id } }); else
(error: Error) =>
if (event) res.status(200).json({ data: event }); res.status(404).json({
if (!event) res.status(404).json({ message: "Event type not found" }); message: "EventType was not found",
} else { error,
// Reject any other HTTP method than POST });
res.status(405).json({ message: "Only GET Method allowed" });
}
} }
export default withValidQueryIdTransformParseInt(eventType); export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(eventTypeById));

View File

@ -1,21 +1,35 @@
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { EventType } from "@calcom/prisma/client";
type ResponseData = { import { withMiddleware } from "@lib/helpers/withMiddleware";
data?: EventType[]; import { EventTypesResponse } from "@lib/types";
message?: string; import { schemaEventTypePublic } from "@lib/validations/eventType";
error?: unknown;
};
export default async function eventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) { /**
const { method } = req; * @swagger
if (method === "GET") { * /api/eventTypes:
const data = await prisma.eventType.findMany(); * get:
res.status(200).json({ data }); * description: Returns all eventTypes
} else { * responses:
// Reject any other HTTP method than POST * 200:
res.status(405).json({ message: "Only GET Method allowed" }); * description: OK
} * 401:
* description: Authorization information is missing or invalid.
* 404:
* description: No eventTypes were found
*/
async function allEventTypes(_: NextApiRequest, res: NextApiResponse<EventTypesResponse>) {
const eventTypes = await prisma.eventType.findMany();
const data = eventTypes.map((eventType) => schemaEventTypePublic.parse(eventType));
if (data) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "No EventTypes were found",
error,
});
} }
export default withMiddleware("HTTP_GET")(allEventTypes);

View File

@ -1,30 +1,43 @@
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { EventType } from "@calcom/prisma/client";
import { schemaEventType, withValidEventType } from "@lib/validations/eventType"; import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { EventTypeResponse } from "@lib/types";
import {
schemaEventTypeBodyParams,
schemaEventTypePublic,
withValidEventType,
} from "@lib/validations/eventType";
type ResponseData = { /**
data?: EventType; * @swagger
message?: string; * /api/eventTypes/new:
error?: string; * post:
}; * description: Creates a new eventType
* responses:
* 201:
* description: OK, eventType created
* model: EventType
* 400:
* description: Bad request. EventType body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
async function createEventType(req: NextApiRequest, res: NextApiResponse<EventTypeResponse>) {
const safe = schemaEventTypeBodyParams.safeParse(req.body);
if (!safe.success) throw new Error("Invalid request body", safe.error);
async function createEventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) { const eventType = await prisma.eventType.create({ data: safe.data });
const { body, method } = req; const data = schemaEventTypePublic.parse(eventType);
if (method === "POST") {
const safe = schemaEventType.safeParse(body); if (data) res.status(201).json({ data, message: "EventType created successfully" });
if (safe.success && safe.data) { else
await prisma.eventType (error: Error) =>
.create({ data: safe.data }) res.status(400).json({
.then((event) => res.status(201).json({ data: event })) message: "Could not create new eventType",
.catch((error) => res.status(400).json({ message: "Could not create event type", error: error })); error,
} });
} else {
// Reject any other HTTP method than POST
res.status(405).json({ error: "Only POST Method allowed" });
}
} }
export default withValidEventType(createEventType); export default withMiddleware("HTTP_POST")(withValidEventType(createEventType));