first commit
This commit is contained in:
29
calcom/apps/api/v1/lib/validations/api-key.ts
Normal file
29
calcom/apps/api/v1/lib/validations/api-key.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _ApiKeyModel as ApiKey } from "@calcom/prisma/zod";
|
||||
|
||||
export const apiKeyCreateBodySchema = ApiKey.pick({
|
||||
note: true,
|
||||
expiresAt: true,
|
||||
userId: true,
|
||||
})
|
||||
.partial({ userId: true })
|
||||
.merge(z.object({ neverExpires: z.boolean().optional() }))
|
||||
.strict();
|
||||
|
||||
export const apiKeyEditBodySchema = ApiKey.pick({
|
||||
note: true,
|
||||
})
|
||||
.partial()
|
||||
.strict();
|
||||
|
||||
export const apiKeyPublicSchema = ApiKey.pick({
|
||||
id: true,
|
||||
userId: true,
|
||||
note: true,
|
||||
createdAt: true,
|
||||
expiresAt: true,
|
||||
lastUsedAt: true,
|
||||
/** We might never want to expose these. Leaving this a as reminder. */
|
||||
// hashedKey: true,
|
||||
});
|
||||
39
calcom/apps/api/v1/lib/validations/attendee.ts
Normal file
39
calcom/apps/api/v1/lib/validations/attendee.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _AttendeeModel as Attendee } from "@calcom/prisma/zod";
|
||||
|
||||
import { timeZone } from "~/lib/validations/shared/timeZone";
|
||||
|
||||
export const schemaAttendeeBaseBodyParams = Attendee.pick({
|
||||
bookingId: true,
|
||||
email: true,
|
||||
name: true,
|
||||
timeZone: true,
|
||||
});
|
||||
|
||||
const schemaAttendeeCreateParams = z
|
||||
.object({
|
||||
bookingId: z.number().int(),
|
||||
email: z.string().email(),
|
||||
name: z.string(),
|
||||
timeZone: timeZone,
|
||||
})
|
||||
.strict();
|
||||
|
||||
const schemaAttendeeEditParams = z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
email: z.string().email().optional(),
|
||||
timeZone: timeZone.optional(),
|
||||
})
|
||||
.strict();
|
||||
export const schemaAttendeeEditBodyParams = schemaAttendeeBaseBodyParams.merge(schemaAttendeeEditParams);
|
||||
export const schemaAttendeeCreateBodyParams = schemaAttendeeBaseBodyParams.merge(schemaAttendeeCreateParams);
|
||||
|
||||
export const schemaAttendeeReadPublic = Attendee.pick({
|
||||
id: true,
|
||||
bookingId: true,
|
||||
name: true,
|
||||
email: true,
|
||||
timeZone: true,
|
||||
});
|
||||
56
calcom/apps/api/v1/lib/validations/availability.ts
Normal file
56
calcom/apps/api/v1/lib/validations/availability.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _AvailabilityModel as Availability, _ScheduleModel as Schedule } from "@calcom/prisma/zod";
|
||||
import { denullishShape } from "@calcom/prisma/zod-utils";
|
||||
|
||||
export const schemaAvailabilityBaseBodyParams = /** We make all these properties required */ denullishShape(
|
||||
Availability.pick({
|
||||
/** We need to pass the schedule where this availability belongs to */
|
||||
scheduleId: true,
|
||||
})
|
||||
);
|
||||
|
||||
export const schemaAvailabilityReadPublic = Availability.pick({
|
||||
id: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
date: true,
|
||||
scheduleId: true,
|
||||
days: true,
|
||||
// eventTypeId: true /** @deprecated */,
|
||||
// userId: true /** @deprecated */,
|
||||
}).merge(z.object({ success: z.boolean().optional(), Schedule: Schedule.partial() }).partial());
|
||||
|
||||
const schemaAvailabilityCreateParams = z
|
||||
.object({
|
||||
startTime: z.date().or(z.string()),
|
||||
endTime: z.date().or(z.string()),
|
||||
days: z.array(z.number()).optional(),
|
||||
date: z.date().or(z.string()).optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
const schemaAvailabilityEditParams = z
|
||||
.object({
|
||||
startTime: z.date().or(z.string()).optional(),
|
||||
endTime: z.date().or(z.string()).optional(),
|
||||
days: z.array(z.number()).optional(),
|
||||
date: z.date().or(z.string()).optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaAvailabilityEditBodyParams = schemaAvailabilityEditParams;
|
||||
|
||||
export const schemaAvailabilityCreateBodyParams = schemaAvailabilityBaseBodyParams.merge(
|
||||
schemaAvailabilityCreateParams
|
||||
);
|
||||
|
||||
export const schemaAvailabilityReadBodyParams = z
|
||||
.object({
|
||||
userId: z.union([z.number(), z.array(z.number())]),
|
||||
})
|
||||
.partial();
|
||||
|
||||
export const schemaSingleAvailabilityReadBodyParams = z.object({
|
||||
userId: z.number(),
|
||||
});
|
||||
28
calcom/apps/api/v1/lib/validations/booking-reference.ts
Normal file
28
calcom/apps/api/v1/lib/validations/booking-reference.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { _BookingReferenceModel as BookingReference } from "@calcom/prisma/zod";
|
||||
import { denullishShape } from "@calcom/prisma/zod-utils";
|
||||
|
||||
export const schemaBookingReferenceBaseBodyParams = BookingReference.pick({
|
||||
type: true,
|
||||
bookingId: true,
|
||||
uid: true,
|
||||
meetingId: true,
|
||||
meetingPassword: true,
|
||||
meetingUrl: true,
|
||||
deleted: true,
|
||||
}).partial();
|
||||
|
||||
export const schemaBookingReferenceReadPublic = BookingReference.pick({
|
||||
id: true,
|
||||
type: true,
|
||||
bookingId: true,
|
||||
uid: true,
|
||||
meetingId: true,
|
||||
meetingPassword: true,
|
||||
meetingUrl: true,
|
||||
deleted: true,
|
||||
});
|
||||
|
||||
export const schemaBookingCreateBodyParams = BookingReference.omit({ id: true, bookingId: true })
|
||||
.merge(denullishShape(BookingReference.pick({ bookingId: true })))
|
||||
.strict();
|
||||
export const schemaBookingEditBodyParams = schemaBookingCreateBodyParams.partial();
|
||||
88
calcom/apps/api/v1/lib/validations/booking.ts
Normal file
88
calcom/apps/api/v1/lib/validations/booking.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _BookingModel as Booking, _AttendeeModel, _UserModel, _PaymentModel } from "@calcom/prisma/zod";
|
||||
import { extendedBookingCreateBody, iso8601 } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { schemaQueryUserId } from "./shared/queryUserId";
|
||||
|
||||
const schemaBookingBaseBodyParams = Booking.pick({
|
||||
uid: true,
|
||||
userId: true,
|
||||
eventTypeId: true,
|
||||
title: true,
|
||||
description: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
status: true,
|
||||
}).partial();
|
||||
|
||||
export const schemaBookingCreateBodyParams = extendedBookingCreateBody.merge(schemaQueryUserId.partial());
|
||||
|
||||
export const schemaBookingGetParams = z.object({
|
||||
dateFrom: iso8601.optional(),
|
||||
dateTo: iso8601.optional(),
|
||||
order: z.enum(["asc", "desc"]).default("asc"),
|
||||
sortBy: z.enum(["createdAt", "updatedAt"]).optional(),
|
||||
});
|
||||
|
||||
const schemaBookingEditParams = z
|
||||
.object({
|
||||
title: z.string().optional(),
|
||||
startTime: iso8601.optional(),
|
||||
endTime: iso8601.optional(),
|
||||
// Not supporting responses in edit as that might require re-triggering emails
|
||||
// responses
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaBookingEditBodyParams = schemaBookingBaseBodyParams
|
||||
.merge(schemaBookingEditParams)
|
||||
.omit({ uid: true });
|
||||
|
||||
export const schemaBookingReadPublic = Booking.extend({
|
||||
attendees: z
|
||||
.array(
|
||||
_AttendeeModel.pick({
|
||||
email: true,
|
||||
name: true,
|
||||
timeZone: true,
|
||||
locale: true,
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
user: _UserModel
|
||||
.pick({
|
||||
email: true,
|
||||
name: true,
|
||||
timeZone: true,
|
||||
locale: true,
|
||||
})
|
||||
.nullish(),
|
||||
payment: z
|
||||
.array(
|
||||
_PaymentModel.pick({
|
||||
id: true,
|
||||
success: true,
|
||||
paymentOption: true,
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
responses: z.record(z.any()).nullable(),
|
||||
}).pick({
|
||||
id: true,
|
||||
userId: true,
|
||||
description: true,
|
||||
eventTypeId: true,
|
||||
uid: true,
|
||||
title: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
timeZone: true,
|
||||
attendees: true,
|
||||
user: true,
|
||||
payment: true,
|
||||
metadata: true,
|
||||
status: true,
|
||||
responses: true,
|
||||
fromReschedule: true,
|
||||
});
|
||||
18
calcom/apps/api/v1/lib/validations/connected-calendar.ts
Normal file
18
calcom/apps/api/v1/lib/validations/connected-calendar.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { z } from "zod";
|
||||
|
||||
const CalendarSchema = z.object({
|
||||
externalId: z.string(),
|
||||
name: z.string(),
|
||||
primary: z.boolean(),
|
||||
readOnly: z.boolean(),
|
||||
});
|
||||
|
||||
const IntegrationSchema = z.object({
|
||||
name: z.string(),
|
||||
appId: z.string(),
|
||||
userId: z.number(),
|
||||
integration: z.string(),
|
||||
calendars: z.array(CalendarSchema),
|
||||
});
|
||||
|
||||
export const schemaConnectedCalendarsReadPublic = z.array(IntegrationSchema);
|
||||
64
calcom/apps/api/v1/lib/validations/credential-sync.ts
Normal file
64
calcom/apps/api/v1/lib/validations/credential-sync.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
|
||||
const userId = z.string().transform((val) => {
|
||||
const userIdInt = parseInt(val);
|
||||
|
||||
if (isNaN(userIdInt)) {
|
||||
throw new HttpError({ message: "userId is not a valid number", statusCode: 400 });
|
||||
}
|
||||
|
||||
return userIdInt;
|
||||
});
|
||||
const appSlug = z.string();
|
||||
const credentialId = z.string().transform((val) => {
|
||||
const credentialIdInt = parseInt(val);
|
||||
|
||||
if (isNaN(credentialIdInt)) {
|
||||
throw new HttpError({ message: "credentialId is not a valid number", statusCode: 400 });
|
||||
}
|
||||
|
||||
return credentialIdInt;
|
||||
});
|
||||
const encryptedKey = z.string();
|
||||
|
||||
export const schemaCredentialGetParams = z.object({
|
||||
userId,
|
||||
appSlug: appSlug.optional(),
|
||||
});
|
||||
|
||||
export const schemaCredentialPostParams = z.object({
|
||||
userId,
|
||||
createSelectedCalendar: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((val) => {
|
||||
return val === "true";
|
||||
}),
|
||||
createDestinationCalendar: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((val) => {
|
||||
return val === "true";
|
||||
}),
|
||||
});
|
||||
|
||||
export const schemaCredentialPostBody = z.object({
|
||||
appSlug,
|
||||
encryptedKey,
|
||||
});
|
||||
|
||||
export const schemaCredentialPatchParams = z.object({
|
||||
userId,
|
||||
credentialId,
|
||||
});
|
||||
|
||||
export const schemaCredentialPatchBody = z.object({
|
||||
encryptedKey,
|
||||
});
|
||||
|
||||
export const schemaCredentialDeleteParams = z.object({
|
||||
userId,
|
||||
credentialId,
|
||||
});
|
||||
48
calcom/apps/api/v1/lib/validations/destination-calendar.ts
Normal file
48
calcom/apps/api/v1/lib/validations/destination-calendar.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _DestinationCalendarModel as DestinationCalendar } from "@calcom/prisma/zod";
|
||||
|
||||
export const schemaDestinationCalendarBaseBodyParams = DestinationCalendar.pick({
|
||||
integration: true,
|
||||
externalId: true,
|
||||
eventTypeId: true,
|
||||
bookingId: true,
|
||||
userId: true,
|
||||
}).partial();
|
||||
|
||||
const schemaDestinationCalendarCreateParams = z
|
||||
.object({
|
||||
integration: z.string(),
|
||||
externalId: z.string(),
|
||||
eventTypeId: z.number().optional(),
|
||||
bookingId: z.number().optional(),
|
||||
userId: z.number().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaDestinationCalendarCreateBodyParams = schemaDestinationCalendarBaseBodyParams.merge(
|
||||
schemaDestinationCalendarCreateParams
|
||||
);
|
||||
|
||||
const schemaDestinationCalendarEditParams = z
|
||||
.object({
|
||||
integration: z.string().optional(),
|
||||
externalId: z.string().optional(),
|
||||
eventTypeId: z.number().optional(),
|
||||
bookingId: z.number().optional(),
|
||||
userId: z.number().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaDestinationCalendarEditBodyParams = schemaDestinationCalendarBaseBodyParams.merge(
|
||||
schemaDestinationCalendarEditParams
|
||||
);
|
||||
|
||||
export const schemaDestinationCalendarReadPublic = DestinationCalendar.pick({
|
||||
id: true,
|
||||
integration: true,
|
||||
externalId: true,
|
||||
eventTypeId: true,
|
||||
bookingId: true,
|
||||
userId: true,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import { _EventTypeCustomInputModel as EventTypeCustomInput } from "@calcom/prisma/zod";
|
||||
|
||||
export const schemaEventTypeCustomInputBaseBodyParams = EventTypeCustomInput.omit({
|
||||
id: true,
|
||||
});
|
||||
|
||||
export const schemaEventTypeCustomInputPublic = EventTypeCustomInput.omit({});
|
||||
|
||||
export const schemaEventTypeCustomInputBodyParams = schemaEventTypeCustomInputBaseBodyParams.strict();
|
||||
|
||||
export const schemaEventTypeCustomInputEditBodyParams = schemaEventTypeCustomInputBaseBodyParams
|
||||
.partial()
|
||||
.strict();
|
||||
173
calcom/apps/api/v1/lib/validations/event-type.ts
Normal file
173
calcom/apps/api/v1/lib/validations/event-type.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import { _EventTypeModel as EventType, _HostModel } from "@calcom/prisma/zod";
|
||||
import { customInputSchema, eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { Frequency } from "~/lib/types";
|
||||
|
||||
import { jsonSchema } from "./shared/jsonSchema";
|
||||
import { schemaQueryUserId } from "./shared/queryUserId";
|
||||
import { timeZone } from "./shared/timeZone";
|
||||
|
||||
const recurringEventInputSchema = z.object({
|
||||
dtstart: z.string().optional(),
|
||||
interval: z.number().int().optional(),
|
||||
count: z.number().int().optional(),
|
||||
freq: z.nativeEnum(Frequency).optional(),
|
||||
until: z.string().optional(),
|
||||
tzid: timeZone.optional(),
|
||||
});
|
||||
|
||||
const hostSchema = _HostModel.pick({
|
||||
isFixed: true,
|
||||
userId: true,
|
||||
});
|
||||
|
||||
export const childrenSchema = z.object({
|
||||
id: z.number().int(),
|
||||
userId: z.number().int(),
|
||||
});
|
||||
|
||||
export const schemaEventTypeBaseBodyParams = EventType.pick({
|
||||
title: true,
|
||||
description: true,
|
||||
slug: true,
|
||||
length: true,
|
||||
hidden: true,
|
||||
position: true,
|
||||
eventName: true,
|
||||
timeZone: true,
|
||||
schedulingType: true,
|
||||
// START Limit future bookings
|
||||
periodType: true,
|
||||
periodStartDate: true,
|
||||
periodEndDate: true,
|
||||
periodDays: true,
|
||||
periodCountCalendarDays: true,
|
||||
// END Limit future bookings
|
||||
requiresConfirmation: true,
|
||||
disableGuests: true,
|
||||
hideCalendarNotes: true,
|
||||
minimumBookingNotice: true,
|
||||
parentId: true,
|
||||
beforeEventBuffer: true,
|
||||
afterEventBuffer: true,
|
||||
teamId: true,
|
||||
price: true,
|
||||
currency: true,
|
||||
slotInterval: true,
|
||||
successRedirectUrl: true,
|
||||
locations: true,
|
||||
bookingLimits: true,
|
||||
onlyShowFirstAvailableSlot: true,
|
||||
durationLimits: true,
|
||||
assignAllTeamMembers: true,
|
||||
})
|
||||
.merge(
|
||||
z.object({
|
||||
children: z.array(childrenSchema).optional().default([]),
|
||||
hosts: z.array(hostSchema).optional().default([]),
|
||||
})
|
||||
)
|
||||
.partial()
|
||||
.strict();
|
||||
|
||||
const schemaEventTypeCreateParams = z
|
||||
.object({
|
||||
title: z.string(),
|
||||
slug: z.string().transform((s) => slugify(s)),
|
||||
description: z.string().optional().nullable(),
|
||||
length: z.number().int(),
|
||||
metadata: z.any().optional(),
|
||||
recurringEvent: recurringEventInputSchema.optional(),
|
||||
seatsPerTimeSlot: z.number().optional(),
|
||||
seatsShowAttendees: z.boolean().optional(),
|
||||
seatsShowAvailabilityCount: z.boolean().optional(),
|
||||
bookingFields: eventTypeBookingFields.optional(),
|
||||
scheduleId: z.number().optional(),
|
||||
parentId: z.number().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaEventTypeCreateBodyParams = schemaEventTypeBaseBodyParams
|
||||
.merge(schemaEventTypeCreateParams)
|
||||
.merge(schemaQueryUserId.partial());
|
||||
|
||||
const schemaEventTypeEditParams = z
|
||||
.object({
|
||||
title: z.string().optional(),
|
||||
slug: z
|
||||
.string()
|
||||
.transform((s) => slugify(s))
|
||||
.optional(),
|
||||
length: z.number().int().optional(),
|
||||
seatsPerTimeSlot: z.number().optional(),
|
||||
seatsShowAttendees: z.boolean().optional(),
|
||||
seatsShowAvailabilityCount: z.boolean().optional(),
|
||||
bookingFields: eventTypeBookingFields.optional(),
|
||||
scheduleId: z.number().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaEventTypeEditBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeEditParams);
|
||||
export const schemaEventTypeReadPublic = EventType.pick({
|
||||
id: true,
|
||||
title: true,
|
||||
slug: true,
|
||||
length: true,
|
||||
hidden: true,
|
||||
position: true,
|
||||
userId: true,
|
||||
teamId: true,
|
||||
scheduleId: true,
|
||||
eventName: true,
|
||||
timeZone: true,
|
||||
periodType: true,
|
||||
periodStartDate: true,
|
||||
periodEndDate: true,
|
||||
periodDays: true,
|
||||
periodCountCalendarDays: true,
|
||||
requiresConfirmation: true,
|
||||
recurringEvent: true,
|
||||
disableGuests: true,
|
||||
hideCalendarNotes: true,
|
||||
minimumBookingNotice: true,
|
||||
beforeEventBuffer: true,
|
||||
afterEventBuffer: true,
|
||||
schedulingType: true,
|
||||
price: true,
|
||||
currency: true,
|
||||
slotInterval: true,
|
||||
parentId: true,
|
||||
successRedirectUrl: true,
|
||||
description: true,
|
||||
locations: true,
|
||||
metadata: true,
|
||||
seatsPerTimeSlot: true,
|
||||
seatsShowAttendees: true,
|
||||
seatsShowAvailabilityCount: true,
|
||||
bookingFields: true,
|
||||
bookingLimits: true,
|
||||
onlyShowFirstAvailableSlot: true,
|
||||
durationLimits: true,
|
||||
}).merge(
|
||||
z.object({
|
||||
children: z.array(childrenSchema).optional().default([]),
|
||||
hosts: z.array(hostSchema).optional().default([]),
|
||||
locations: z
|
||||
.array(
|
||||
z.object({
|
||||
link: z.string().optional(),
|
||||
address: z.string().optional(),
|
||||
hostPhoneNumber: z.string().optional(),
|
||||
type: z.any().optional(),
|
||||
})
|
||||
)
|
||||
.nullable(),
|
||||
metadata: jsonSchema.nullable(),
|
||||
customInputs: customInputSchema.array().optional(),
|
||||
link: z.string().optional(),
|
||||
bookingFields: eventTypeBookingFields.optional().nullable(),
|
||||
})
|
||||
);
|
||||
68
calcom/apps/api/v1/lib/validations/membership.ts
Normal file
68
calcom/apps/api/v1/lib/validations/membership.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
import { _MembershipModel as Membership, _TeamModel } from "@calcom/prisma/zod";
|
||||
import { stringOrNumber } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { schemaQueryIdAsString } from "~/lib/validations/shared/queryIdString";
|
||||
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
export const schemaMembershipBaseBodyParams = Membership.omit({});
|
||||
|
||||
const schemaMembershipRequiredParams = z.object({
|
||||
teamId: z.number(),
|
||||
});
|
||||
|
||||
export const membershipCreateBodySchema = Membership.omit({ id: true })
|
||||
.partial({
|
||||
accepted: true,
|
||||
role: true,
|
||||
disableImpersonation: true,
|
||||
})
|
||||
.transform((v) => ({
|
||||
accepted: false,
|
||||
role: MembershipRole.MEMBER,
|
||||
disableImpersonation: false,
|
||||
...v,
|
||||
}));
|
||||
|
||||
export const membershipEditBodySchema = Membership.omit({
|
||||
/** To avoid complication, let's avoid updating these, instead you can delete and create a new invite */
|
||||
teamId: true,
|
||||
userId: true,
|
||||
id: true,
|
||||
})
|
||||
.partial({
|
||||
accepted: true,
|
||||
role: true,
|
||||
disableImpersonation: true,
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaMembershipBodyParams = schemaMembershipBaseBodyParams.merge(
|
||||
schemaMembershipRequiredParams
|
||||
);
|
||||
|
||||
export const schemaMembershipPublic = Membership.merge(z.object({ team: _TeamModel }).partial());
|
||||
|
||||
/** We extract userId and teamId from compound ID string */
|
||||
export const membershipIdSchema = schemaQueryIdAsString
|
||||
// So we can query additional team data in memberships
|
||||
.merge(z.object({ teamId: z.union([stringOrNumber, z.array(stringOrNumber)]) }).partial())
|
||||
.transform((v, ctx) => {
|
||||
const [userIdStr, teamIdStr] = v.id.split("_");
|
||||
const userIdInt = schemaQueryIdParseInt.safeParse({ id: userIdStr });
|
||||
const teamIdInt = schemaQueryIdParseInt.safeParse({ id: teamIdStr });
|
||||
if (!userIdInt.success) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "userId is not a number" });
|
||||
return z.NEVER;
|
||||
}
|
||||
if (!teamIdInt.success) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "teamId is not a number " });
|
||||
return z.NEVER;
|
||||
}
|
||||
return {
|
||||
userId: userIdInt.data.id,
|
||||
teamId: teamIdInt.data.id,
|
||||
};
|
||||
});
|
||||
5
calcom/apps/api/v1/lib/validations/payment.ts
Normal file
5
calcom/apps/api/v1/lib/validations/payment.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { _PaymentModel as Payment } from "@calcom/prisma/zod";
|
||||
|
||||
// FIXME: Payment seems a delicate endpoint, do we need to remove anything here?
|
||||
export const schemaPaymentBodyParams = Payment.omit({ id: true });
|
||||
export const schemaPaymentPublic = Payment.omit({ externalId: true });
|
||||
17
calcom/apps/api/v1/lib/validations/reminder-mail.ts
Normal file
17
calcom/apps/api/v1/lib/validations/reminder-mail.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _ReminderMailModel as ReminderMail } from "@calcom/prisma/zod";
|
||||
|
||||
export const schemaReminderMailBaseBodyParams = ReminderMail.omit({ id: true }).partial();
|
||||
|
||||
export const schemaReminderMailPublic = ReminderMail.omit({});
|
||||
|
||||
const schemaReminderMailRequiredParams = z.object({
|
||||
referenceId: z.number().int(),
|
||||
reminderType: z.enum(["PENDING_BOOKING_CONFIRMATION"]),
|
||||
elapsedMinutes: z.number().int(),
|
||||
});
|
||||
|
||||
export const schemaReminderMailBodyParams = schemaReminderMailBaseBodyParams.merge(
|
||||
schemaReminderMailRequiredParams
|
||||
);
|
||||
43
calcom/apps/api/v1/lib/validations/schedule.ts
Normal file
43
calcom/apps/api/v1/lib/validations/schedule.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { _ScheduleModel as Schedule, _AvailabilityModel as Availability } from "@calcom/prisma/zod";
|
||||
|
||||
import { timeZone } from "./shared/timeZone";
|
||||
|
||||
const schemaScheduleBaseBodyParams = Schedule.omit({ id: true, timeZone: true }).partial();
|
||||
|
||||
export const schemaSingleScheduleBodyParams = schemaScheduleBaseBodyParams.merge(
|
||||
z.object({ userId: z.number().optional(), timeZone: timeZone.optional() })
|
||||
);
|
||||
|
||||
export const schemaCreateScheduleBodyParams = schemaScheduleBaseBodyParams.merge(
|
||||
z.object({ userId: z.number().optional(), name: z.string(), timeZone })
|
||||
);
|
||||
|
||||
export const schemaSchedulePublic = z
|
||||
.object({ id: z.number() })
|
||||
.merge(Schedule)
|
||||
.merge(
|
||||
z.object({
|
||||
availability: z
|
||||
.array(
|
||||
Availability.pick({
|
||||
id: true,
|
||||
eventTypeId: true,
|
||||
date: true,
|
||||
days: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
})
|
||||
)
|
||||
.transform((v) =>
|
||||
v.map((item) => ({
|
||||
...item,
|
||||
startTime: dayjs.utc(item.startTime).format("HH:mm:ss"),
|
||||
endTime: dayjs.utc(item.endTime).format("HH:mm:ss"),
|
||||
}))
|
||||
)
|
||||
.optional(),
|
||||
})
|
||||
);
|
||||
48
calcom/apps/api/v1/lib/validations/selected-calendar.ts
Normal file
48
calcom/apps/api/v1/lib/validations/selected-calendar.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import z from "zod";
|
||||
|
||||
import { _SelectedCalendarModel as SelectedCalendar } from "@calcom/prisma/zod";
|
||||
|
||||
import { schemaQueryIdAsString } from "./shared/queryIdString";
|
||||
import { schemaQueryIdParseInt } from "./shared/queryIdTransformParseInt";
|
||||
|
||||
export const schemaSelectedCalendarBaseBodyParams = SelectedCalendar;
|
||||
|
||||
export const schemaSelectedCalendarPublic = SelectedCalendar.omit({});
|
||||
|
||||
export const schemaSelectedCalendarBodyParams = schemaSelectedCalendarBaseBodyParams.partial({
|
||||
userId: true,
|
||||
});
|
||||
|
||||
export const schemaSelectedCalendarUpdateBodyParams = schemaSelectedCalendarBaseBodyParams.partial();
|
||||
|
||||
export const selectedCalendarIdSchema = schemaQueryIdAsString.transform((v, ctx) => {
|
||||
/** We can assume the first part is the userId since it's an integer */
|
||||
const [userIdStr, ...rest] = v.id.split("_");
|
||||
/** We can assume that the remainder is both the integration type and external id combined */
|
||||
const integration_externalId = rest.join("_");
|
||||
/**
|
||||
* Since we only handle calendars here we can split by `_calendar_` and re add it later on.
|
||||
* This handle special cases like `google_calendar_c_blabla@group.calendar.google.com` and
|
||||
* `hubspot_other_calendar`.
|
||||
**/
|
||||
const [_integration, externalId] = integration_externalId.split("_calendar_");
|
||||
const userIdInt = schemaQueryIdParseInt.safeParse({ id: userIdStr });
|
||||
if (!userIdInt.success) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "userId is not a number" });
|
||||
return z.NEVER;
|
||||
}
|
||||
if (!_integration) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Missing integration" });
|
||||
return z.NEVER;
|
||||
}
|
||||
if (!externalId) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Missing externalId" });
|
||||
return z.NEVER;
|
||||
}
|
||||
return {
|
||||
userId: userIdInt.data.id,
|
||||
/** We re-add the split `_calendar` string */
|
||||
integration: `${_integration}_calendar`,
|
||||
externalId,
|
||||
};
|
||||
});
|
||||
11
calcom/apps/api/v1/lib/validations/shared/baseApiParams.ts
Normal file
11
calcom/apps/api/v1/lib/validations/shared/baseApiParams.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
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().optional(),
|
||||
// version required for supporting /v1/ redirect to query in api as *?version=1
|
||||
version: z.string().optional(),
|
||||
});
|
||||
9
calcom/apps/api/v1/lib/validations/shared/jsonSchema.ts
Normal file
9
calcom/apps/api/v1/lib/validations/shared/jsonSchema.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// Helper schema for JSON fields
|
||||
type Literal = boolean | number | string;
|
||||
type Json = Literal | { [key: string]: Json } | Json[];
|
||||
const literalSchema = z.union([z.string(), z.number(), z.boolean()]);
|
||||
export const jsonSchema: z.ZodSchema<Json> = z.lazy(() =>
|
||||
z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])
|
||||
);
|
||||
@@ -0,0 +1,20 @@
|
||||
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.
|
||||
export const schemaQueryAttendeeEmail = baseApiParams.extend({
|
||||
attendeeEmail: z.string().email(),
|
||||
});
|
||||
|
||||
export const schemaQuerySingleOrMultipleAttendeeEmails = z.object({
|
||||
attendeeEmail: z.union([z.string().email(), z.array(z.string().email())]).optional(),
|
||||
});
|
||||
|
||||
export const withValidQueryAttendeeEmail = withValidation({
|
||||
schema: schemaQueryAttendeeEmail,
|
||||
type: "Zod",
|
||||
mode: "query",
|
||||
});
|
||||
19
calcom/apps/api/v1/lib/validations/shared/queryIdString.ts
Normal file
19
calcom/apps/api/v1/lib/validations/shared/queryIdString.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
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.
|
||||
/** Used for UUID style id queries */
|
||||
export const schemaQueryIdAsString = baseApiParams
|
||||
.extend({
|
||||
id: z.string(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const withValidQueryIdString = withValidation({
|
||||
schema: schemaQueryIdAsString,
|
||||
type: "Zod",
|
||||
mode: "query",
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
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.
|
||||
export const schemaQueryIdParseInt = baseApiParams.extend({
|
||||
id: z.coerce.number(),
|
||||
});
|
||||
|
||||
export const withValidQueryIdTransformParseInt = withValidation({
|
||||
schema: schemaQueryIdParseInt,
|
||||
type: "Zod",
|
||||
mode: "query",
|
||||
});
|
||||
|
||||
export const getTranscriptFromRecordingId = schemaQueryIdParseInt.extend({
|
||||
recordingId: z.string(),
|
||||
});
|
||||
7
calcom/apps/api/v1/lib/validations/shared/querySlug.ts
Normal file
7
calcom/apps/api/v1/lib/validations/shared/querySlug.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { baseApiParams } from "./baseApiParams";
|
||||
|
||||
export const schemaQuerySlug = baseApiParams.extend({
|
||||
slug: z.string().optional(),
|
||||
});
|
||||
21
calcom/apps/api/v1/lib/validations/shared/queryTeamId.ts
Normal file
21
calcom/apps/api/v1/lib/validations/shared/queryTeamId.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
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.
|
||||
export const schemaQueryTeamId = baseApiParams
|
||||
.extend({
|
||||
teamId: z
|
||||
.string()
|
||||
.regex(/^\d+$/)
|
||||
.transform((id) => parseInt(id)),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const withValidQueryTeamId = withValidation({
|
||||
schema: schemaQueryTeamId,
|
||||
type: "Zod",
|
||||
mode: "query",
|
||||
});
|
||||
20
calcom/apps/api/v1/lib/validations/shared/queryUserEmail.ts
Normal file
20
calcom/apps/api/v1/lib/validations/shared/queryUserEmail.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
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.
|
||||
export const schemaQueryUserEmail = baseApiParams.extend({
|
||||
email: z.string().email(),
|
||||
});
|
||||
|
||||
export const schemaQuerySingleOrMultipleUserEmails = z.object({
|
||||
email: z.union([z.string().email(), z.array(z.string().email())]),
|
||||
});
|
||||
|
||||
export const withValidQueryUserEmail = withValidation({
|
||||
schema: schemaQueryUserEmail,
|
||||
type: "Zod",
|
||||
mode: "query",
|
||||
});
|
||||
26
calcom/apps/api/v1/lib/validations/shared/queryUserId.ts
Normal file
26
calcom/apps/api/v1/lib/validations/shared/queryUserId.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { withValidation } from "next-validations";
|
||||
import { z } from "zod";
|
||||
|
||||
import { stringOrNumber } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { baseApiParams } from "./baseApiParams";
|
||||
|
||||
// Extracted out as utility function so can be reused
|
||||
// at different endpoints that require this validation.
|
||||
export const schemaQueryUserId = baseApiParams.extend({
|
||||
userId: stringOrNumber,
|
||||
});
|
||||
|
||||
export const schemaQuerySingleOrMultipleUserIds = z.object({
|
||||
userId: z.union([stringOrNumber, z.array(stringOrNumber)]),
|
||||
});
|
||||
|
||||
export const schemaQuerySingleOrMultipleTeamIds = z.object({
|
||||
teamId: z.union([stringOrNumber, z.array(stringOrNumber)]),
|
||||
});
|
||||
|
||||
export const withValidQueryUserId = withValidation({
|
||||
schema: schemaQueryUserId,
|
||||
type: "Zod",
|
||||
mode: "query",
|
||||
});
|
||||
7
calcom/apps/api/v1/lib/validations/shared/timeZone.ts
Normal file
7
calcom/apps/api/v1/lib/validations/shared/timeZone.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import tzdata from "tzdata";
|
||||
import { z } from "zod";
|
||||
|
||||
// @note: This is a custom validation that checks if the timezone is valid and exists in the tzdb library
|
||||
export const timeZone = z.string().refine((tz: string) => Object.keys(tzdata.zones).includes(tz), {
|
||||
message: `Expected one of the following: ${Object.keys(tzdata.zones).join(", ")}`,
|
||||
});
|
||||
30
calcom/apps/api/v1/lib/validations/team.ts
Normal file
30
calcom/apps/api/v1/lib/validations/team.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _TeamModel as Team } from "@calcom/prisma/zod";
|
||||
|
||||
export const schemaTeamBaseBodyParams = Team.omit({ id: true, createdAt: true }).partial({
|
||||
hideBranding: true,
|
||||
metadata: true,
|
||||
pendingPayment: true,
|
||||
isOrganization: true,
|
||||
isPlatform: true,
|
||||
smsLockState: true,
|
||||
});
|
||||
|
||||
const schemaTeamRequiredParams = z.object({
|
||||
name: z.string().max(255),
|
||||
});
|
||||
|
||||
export const schemaTeamBodyParams = schemaTeamBaseBodyParams.merge(schemaTeamRequiredParams).strict();
|
||||
|
||||
export const schemaTeamUpdateBodyParams = schemaTeamBodyParams.partial();
|
||||
|
||||
const schemaOwnerId = z.object({
|
||||
ownerId: z.number().optional(),
|
||||
});
|
||||
|
||||
export const schemaTeamCreateBodyParams = schemaTeamBodyParams.merge(schemaOwnerId).strict();
|
||||
|
||||
export const schemaTeamReadPublic = Team.omit({});
|
||||
|
||||
export const schemaTeamsReadPublic = z.array(schemaTeamReadPublic);
|
||||
179
calcom/apps/api/v1/lib/validations/user.ts
Normal file
179
calcom/apps/api/v1/lib/validations/user.ts
Normal file
@@ -0,0 +1,179 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { checkUsername } from "@calcom/lib/server/checkUsername";
|
||||
import { _UserModel as User } from "@calcom/prisma/zod";
|
||||
import { iso8601 } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { isValidBase64Image } from "~/lib/utils/isValidBase64Image";
|
||||
import { timeZone } from "~/lib/validations/shared/timeZone";
|
||||
|
||||
// @note: These are the ONLY values allowed as weekStart. So user don't introduce bad data.
|
||||
enum weekdays {
|
||||
MONDAY = "Monday",
|
||||
TUESDAY = "Tuesday",
|
||||
WEDNESDAY = "Wednesday",
|
||||
THURSDAY = "Thursday",
|
||||
FRIDAY = "Friday",
|
||||
SATURDAY = "Saturday",
|
||||
SUNDAY = "Sunday",
|
||||
}
|
||||
|
||||
// @note: extracted from apps/web/next-i18next.config.js, update if new locales.
|
||||
enum locales {
|
||||
EN = "en",
|
||||
FR = "fr",
|
||||
IT = "it",
|
||||
RU = "ru",
|
||||
ES = "es",
|
||||
DE = "de",
|
||||
PT = "pt",
|
||||
RO = "ro",
|
||||
NL = "nl",
|
||||
PT_BR = "pt-BR",
|
||||
// ES_419 = "es-419", // Disabled until Crowdin reaches at least 80% completion
|
||||
KO = "ko",
|
||||
JA = "ja",
|
||||
PL = "pl",
|
||||
AR = "ar",
|
||||
IW = "iw",
|
||||
ZH_CN = "zh-CN",
|
||||
ZH_TW = "zh-TW",
|
||||
CS = "cs",
|
||||
SR = "sr",
|
||||
SV = "sv",
|
||||
VI = "vi",
|
||||
}
|
||||
enum theme {
|
||||
DARK = "dark",
|
||||
LIGHT = "light",
|
||||
}
|
||||
|
||||
enum timeFormat {
|
||||
TWELVE = 12,
|
||||
TWENTY_FOUR = 24,
|
||||
}
|
||||
|
||||
const usernameSchema = z
|
||||
.string()
|
||||
.transform((v) => v.toLowerCase())
|
||||
// .refine(() => {})
|
||||
.superRefine(async (val, ctx) => {
|
||||
if (val) {
|
||||
const result = await checkUsername(val);
|
||||
if (!result.available) ctx.addIssue({ code: z.ZodIssueCode.custom, message: "already_in_use_error" });
|
||||
if (result.premium) ctx.addIssue({ code: z.ZodIssueCode.custom, message: "premium_username" });
|
||||
}
|
||||
});
|
||||
|
||||
// @note: These are the values that are editable via PATCH method on the user Model
|
||||
export const schemaUserBaseBodyParams = User.pick({
|
||||
name: true,
|
||||
email: true,
|
||||
username: true,
|
||||
bio: true,
|
||||
timeZone: true,
|
||||
weekStart: true,
|
||||
theme: true,
|
||||
appTheme: true,
|
||||
defaultScheduleId: true,
|
||||
locale: true,
|
||||
hideBranding: true,
|
||||
timeFormat: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
allowDynamicBooking: true,
|
||||
role: true,
|
||||
// @note: disallowing avatar changes via API for now. We can add it later if needed. User should upload image via UI.
|
||||
// avatar: true,
|
||||
}).partial();
|
||||
// @note: partial() is used to allow for the user to edit only the fields they want to edit making all optional,
|
||||
// if want to make any required do it in the schemaRequiredParams
|
||||
|
||||
// Here we can both require or not (adding optional or nullish) and also rewrite validations for any value
|
||||
// for example making weekStart only accept weekdays as input
|
||||
const schemaUserEditParams = z.object({
|
||||
email: z.string().email().toLowerCase(),
|
||||
username: usernameSchema,
|
||||
weekStart: z.nativeEnum(weekdays).optional(),
|
||||
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
darkBrandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
hideBranding: z.boolean().optional(),
|
||||
timeZone: timeZone.optional(),
|
||||
theme: z.nativeEnum(theme).optional().nullable(),
|
||||
appTheme: z.nativeEnum(theme).optional().nullable(),
|
||||
timeFormat: z.nativeEnum(timeFormat).optional(),
|
||||
defaultScheduleId: z
|
||||
.number()
|
||||
.refine((id: number) => id > 0)
|
||||
.optional()
|
||||
.nullable(),
|
||||
locale: z.nativeEnum(locales).optional().nullable(),
|
||||
avatar: z.string().refine(isValidBase64Image).optional(),
|
||||
});
|
||||
|
||||
// @note: These are the values that are editable via PATCH method on the user Model,
|
||||
// merging both BaseBodyParams with RequiredParams, and omiting whatever we want at the end.
|
||||
|
||||
const schemaUserCreateParams = z.object({
|
||||
email: z.string().email().toLowerCase(),
|
||||
username: usernameSchema,
|
||||
weekStart: z.nativeEnum(weekdays).optional(),
|
||||
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
darkBrandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
hideBranding: z.boolean().optional(),
|
||||
timeZone: timeZone.optional(),
|
||||
theme: z.nativeEnum(theme).optional().nullable(),
|
||||
appTheme: z.nativeEnum(theme).optional().nullable(),
|
||||
timeFormat: z.nativeEnum(timeFormat).optional(),
|
||||
defaultScheduleId: z
|
||||
.number()
|
||||
.refine((id: number) => id > 0)
|
||||
.optional()
|
||||
.nullable(),
|
||||
locale: z.nativeEnum(locales).optional(),
|
||||
createdDate: iso8601.optional(),
|
||||
avatar: z.string().refine(isValidBase64Image).optional(),
|
||||
});
|
||||
|
||||
// @note: These are the values that are editable via PATCH method on the user Model,
|
||||
// merging both BaseBodyParams with RequiredParams, and omiting whatever we want at the end.
|
||||
export const schemaUserEditBodyParams = schemaUserBaseBodyParams
|
||||
.merge(schemaUserEditParams)
|
||||
.omit({})
|
||||
.partial()
|
||||
.strict();
|
||||
|
||||
export const schemaUserCreateBodyParams = schemaUserBaseBodyParams
|
||||
.merge(schemaUserCreateParams)
|
||||
.omit({})
|
||||
.strict();
|
||||
|
||||
// @note: These are the values that are always returned when reading a user
|
||||
export const schemaUserReadPublic = User.pick({
|
||||
id: true,
|
||||
username: true,
|
||||
name: true,
|
||||
email: true,
|
||||
emailVerified: true,
|
||||
bio: true,
|
||||
avatar: true,
|
||||
timeZone: true,
|
||||
weekStart: true,
|
||||
endTime: true,
|
||||
bufferTime: true,
|
||||
appTheme: true,
|
||||
theme: true,
|
||||
defaultScheduleId: true,
|
||||
locale: true,
|
||||
timeFormat: true,
|
||||
hideBranding: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
allowDynamicBooking: true,
|
||||
createdDate: true,
|
||||
verified: true,
|
||||
invitedTo: true,
|
||||
role: true,
|
||||
});
|
||||
|
||||
export const schemaUsersReadPublic = z.array(schemaUserReadPublic);
|
||||
57
calcom/apps/api/v1/lib/validations/webhook.ts
Normal file
57
calcom/apps/api/v1/lib/validations/webhook.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { WEBHOOK_TRIGGER_EVENTS } from "@calcom/features/webhooks/lib/constants";
|
||||
import { _WebhookModel as Webhook } from "@calcom/prisma/zod";
|
||||
|
||||
const schemaWebhookBaseBodyParams = Webhook.pick({
|
||||
userId: true,
|
||||
eventTypeId: true,
|
||||
eventTriggers: true,
|
||||
active: true,
|
||||
subscriberUrl: true,
|
||||
payloadTemplate: true,
|
||||
});
|
||||
|
||||
export const schemaWebhookCreateParams = z
|
||||
.object({
|
||||
// subscriberUrl: z.string().url(),
|
||||
// eventTriggers: z.enum(WEBHOOK_TRIGGER_EVENTS).array(),
|
||||
// active: z.boolean(),
|
||||
payloadTemplate: z.string().optional().nullable(),
|
||||
eventTypeId: z.number().optional(),
|
||||
userId: z.number().optional(),
|
||||
secret: z.string().optional().nullable(),
|
||||
// API shouldn't mess with Apps webhooks yet (ie. Zapier)
|
||||
// appId: z.string().optional().nullable(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const schemaWebhookCreateBodyParams = schemaWebhookBaseBodyParams.merge(schemaWebhookCreateParams);
|
||||
|
||||
export const schemaWebhookEditBodyParams = schemaWebhookBaseBodyParams
|
||||
.merge(
|
||||
z.object({
|
||||
eventTriggers: z.enum(WEBHOOK_TRIGGER_EVENTS).array().optional(),
|
||||
secret: z.string().optional().nullable(),
|
||||
})
|
||||
)
|
||||
.partial()
|
||||
.strict();
|
||||
|
||||
export const schemaWebhookReadPublic = Webhook.pick({
|
||||
id: true,
|
||||
userId: true,
|
||||
eventTypeId: true,
|
||||
payloadTemplate: true,
|
||||
eventTriggers: true,
|
||||
// FIXME: We have some invalid urls saved in the DB
|
||||
// subscriberUrl: true,
|
||||
/** @todo: find out how to properly add back and validate those. */
|
||||
// eventType: true,
|
||||
// app: true,
|
||||
appId: true,
|
||||
}).merge(
|
||||
z.object({
|
||||
subscriberUrl: z.string(),
|
||||
})
|
||||
);
|
||||
Reference in New Issue
Block a user