refactor: removed isNotAnApiCall (#13568)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { NextApiRequest } from "next";
|
||||
|
||||
import getBookingDataSchemaForApi from "@calcom/features/bookings/lib/getBookingDataSchemaForApi";
|
||||
import handleNewBooking from "@calcom/features/bookings/lib/handleNewBooking";
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
|
||||
@@ -206,7 +207,7 @@ async function handler(req: NextApiRequest) {
|
||||
const { userId, isAdmin } = req;
|
||||
if (isAdmin) req.userId = req.body.userId || userId;
|
||||
|
||||
return await handleNewBooking(req);
|
||||
return await handleNewBooking(req, getBookingDataSchemaForApi);
|
||||
}
|
||||
|
||||
export default defaultResponder(handler);
|
||||
|
||||
@@ -17,9 +17,7 @@ async function handler(req: NextApiRequest & { userId?: number }, res: NextApiRe
|
||||
const session = await getServerSession({ req, res });
|
||||
/* To mimic API behavior and comply with types */
|
||||
req.userId = session?.user?.id || -1;
|
||||
const booking = await handleNewBooking(req, {
|
||||
isNotAnApiCall: true,
|
||||
});
|
||||
const booking = await handleNewBooking(req);
|
||||
return booking;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,7 @@ async function handler(req: NextApiRequest & { userId?: number }, res: NextApiRe
|
||||
noEmail: false,
|
||||
};
|
||||
|
||||
const firstBookingResult = await handleNewBooking(recurringEventReq, {
|
||||
isNotAnApiCall: true,
|
||||
});
|
||||
const firstBookingResult = await handleNewBooking(recurringEventReq);
|
||||
luckyUsers = firstBookingResult.luckyUsers?.map((user) => user.id);
|
||||
}
|
||||
|
||||
@@ -92,12 +90,8 @@ async function handler(req: NextApiRequest & { userId?: number }, res: NextApiRe
|
||||
luckyUsers,
|
||||
};
|
||||
|
||||
const promiseEachRecurringBooking: ReturnType<typeof handleNewBooking> = handleNewBooking(
|
||||
recurringEventReq,
|
||||
{
|
||||
isNotAnApiCall: true,
|
||||
}
|
||||
);
|
||||
const promiseEachRecurringBooking: ReturnType<typeof handleNewBooking> =
|
||||
handleNewBooking(recurringEventReq);
|
||||
|
||||
const eachRecurringBooking = await promiseEachRecurringBooking;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export const useBookingForm = ({ event }: IUseBookingForm) => {
|
||||
.object({
|
||||
responses: event?.data
|
||||
? getBookingResponsesSchema({
|
||||
eventType: event?.data,
|
||||
bookingFields: event.data.bookingFields,
|
||||
view: rescheduleUid ? "reschedule" : "booking",
|
||||
})
|
||||
: // Fallback until event is loaded.
|
||||
|
||||
@@ -37,9 +37,7 @@ export function useInitialFormValues({
|
||||
return {};
|
||||
}
|
||||
const querySchema = getBookingResponsesPartialSchema({
|
||||
eventType: {
|
||||
bookingFields: eventType.bookingFields,
|
||||
},
|
||||
bookingFields: eventType.bookingFields,
|
||||
view: rescheduleUid ? "reschedule" : "booking",
|
||||
});
|
||||
|
||||
|
||||
@@ -1,80 +1,20 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
bookingCreateSchemaLegacyPropsForApi,
|
||||
bookingCreateBodySchemaForApi,
|
||||
extendedBookingCreateBody,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
import { extendedBookingCreateBody } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import type { getBookingFieldsWithSystemFields } from "./getBookingFields";
|
||||
import getBookingResponsesSchema from "./getBookingResponsesSchema";
|
||||
import type { getEventTypesFromDB } from "./handleNewBooking";
|
||||
|
||||
const getBookingDataSchema = (
|
||||
rescheduleUid: string | undefined,
|
||||
isNotAnApiCall: boolean,
|
||||
eventType: Awaited<ReturnType<typeof getEventTypesFromDB>>
|
||||
) => {
|
||||
const responsesSchema = getBookingResponsesSchema({
|
||||
eventType: {
|
||||
bookingFields: eventType.bookingFields,
|
||||
},
|
||||
view: rescheduleUid ? "reschedule" : "booking",
|
||||
});
|
||||
const bookingDataSchema = isNotAnApiCall
|
||||
? extendedBookingCreateBody.merge(
|
||||
z.object({
|
||||
responses: responsesSchema,
|
||||
})
|
||||
)
|
||||
: bookingCreateBodySchemaForApi
|
||||
.merge(
|
||||
z.object({
|
||||
responses: responsesSchema.optional(),
|
||||
})
|
||||
)
|
||||
.superRefine((val, ctx) => {
|
||||
if (val.responses && val.customInputs) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message:
|
||||
"Don't use both customInputs and responses. `customInputs` is only there for legacy support.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const legacyProps = Object.keys(bookingCreateSchemaLegacyPropsForApi.shape);
|
||||
|
||||
if (val.responses) {
|
||||
const unwantedProps: string[] = [];
|
||||
legacyProps.forEach((legacyProp) => {
|
||||
if (typeof val[legacyProp as keyof typeof val] !== "undefined") {
|
||||
console.error(
|
||||
`Deprecated: Unexpected falsy value for: ${unwantedProps.join(
|
||||
","
|
||||
)}. They can't be used with \`responses\`. This will become a 400 error in the future.`
|
||||
);
|
||||
}
|
||||
if (val[legacyProp as keyof typeof val]) {
|
||||
unwantedProps.push(legacyProp);
|
||||
}
|
||||
});
|
||||
if (unwantedProps.length) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `Legacy Props: ${unwantedProps.join(",")}. They can't be used with \`responses\``,
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else if (val.customInputs) {
|
||||
const { success } = bookingCreateSchemaLegacyPropsForApi.safeParse(val);
|
||||
if (!success) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `With \`customInputs\` you must specify legacy props ${legacyProps.join(",")}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return bookingDataSchema;
|
||||
const getBookingDataSchema = ({
|
||||
view = "booking",
|
||||
bookingFields,
|
||||
}: {
|
||||
view: "booking" | "reschedule";
|
||||
bookingFields: Awaited<ReturnType<typeof getBookingFieldsWithSystemFields>>;
|
||||
}) => {
|
||||
return extendedBookingCreateBody.merge(
|
||||
z.object({ responses: getBookingResponsesSchema({ bookingFields, view }) })
|
||||
);
|
||||
};
|
||||
|
||||
export default getBookingDataSchema;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
bookingCreateBodySchemaForApi,
|
||||
bookingCreateSchemaLegacyPropsForApi,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
|
||||
import type { getBookingFieldsWithSystemFields } from "./getBookingFields";
|
||||
import getBookingResponsesSchema from "./getBookingResponsesSchema";
|
||||
|
||||
const getBookingDataSchemaForApi = ({
|
||||
view = "booking",
|
||||
bookingFields,
|
||||
}: {
|
||||
view: "booking" | "reschedule";
|
||||
bookingFields: Awaited<ReturnType<typeof getBookingFieldsWithSystemFields>>;
|
||||
}) => {
|
||||
const responsesSchema = getBookingResponsesSchema({ bookingFields, view });
|
||||
return bookingCreateBodySchemaForApi
|
||||
.merge(
|
||||
z.object({
|
||||
responses: responsesSchema.optional(),
|
||||
})
|
||||
)
|
||||
.superRefine((val, ctx) => {
|
||||
if (val.responses && val.customInputs) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message:
|
||||
"Don't use both customInputs and responses. `customInputs` is only there for legacy support.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const legacyProps = Object.keys(bookingCreateSchemaLegacyPropsForApi.shape);
|
||||
|
||||
if (val.responses) {
|
||||
const unwantedProps: string[] = [];
|
||||
legacyProps.forEach((legacyProp) => {
|
||||
if (typeof val[legacyProp as keyof typeof val] !== "undefined") {
|
||||
console.error(
|
||||
`Deprecated: Unexpected falsy value for: ${unwantedProps.join(
|
||||
","
|
||||
)}. They can't be used with \`responses\`. This will become a 400 error in the future.`
|
||||
);
|
||||
}
|
||||
if (val[legacyProp as keyof typeof val]) {
|
||||
unwantedProps.push(legacyProp);
|
||||
}
|
||||
});
|
||||
if (unwantedProps.length) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `Legacy Props: ${unwantedProps.join(",")}. They can't be used with \`responses\``,
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else if (val.customInputs) {
|
||||
const { success } = bookingCreateSchemaLegacyPropsForApi.safeParse(val);
|
||||
if (!success) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `With \`customInputs\` you must specify legacy props ${legacyProps.join(",")}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default getBookingDataSchemaForApi;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,64 +1,55 @@
|
||||
import z from "zod";
|
||||
|
||||
import type { ALL_VIEWS } from "@calcom/features/form-builder/schema";
|
||||
import { fieldTypesSchemaMap, dbReadResponseSchema } from "@calcom/features/form-builder/schema";
|
||||
import { dbReadResponseSchema, fieldTypesSchemaMap } from "@calcom/features/form-builder/schema";
|
||||
import type { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
||||
import { bookingResponses, emailSchemaRefinement } from "@calcom/prisma/zod-utils";
|
||||
|
||||
type EventType = Parameters<typeof preprocess>[0]["eventType"];
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
type View = ALL_VIEWS | (string & {});
|
||||
type BookingFields = (z.infer<typeof eventTypeBookingFields> & z.BRAND<"HAS_SYSTEM_FIELDS">) | null;
|
||||
type CommonParams = { bookingFields: BookingFields; view: View };
|
||||
|
||||
export const bookingResponse = dbReadResponseSchema;
|
||||
export const bookingResponsesDbSchema = z.record(dbReadResponseSchema);
|
||||
|
||||
const catchAllSchema = bookingResponsesDbSchema;
|
||||
|
||||
export const getBookingResponsesPartialSchema = ({
|
||||
eventType,
|
||||
view,
|
||||
}: {
|
||||
eventType: EventType;
|
||||
view: View;
|
||||
}) => {
|
||||
export const getBookingResponsesPartialSchema = ({ bookingFields, view }: CommonParams) => {
|
||||
const schema = bookingResponses.unwrap().partial().and(catchAllSchema);
|
||||
|
||||
return preprocess({ schema, eventType, isPartialSchema: true, view });
|
||||
return preprocess({ schema, bookingFields, isPartialSchema: true, view });
|
||||
};
|
||||
|
||||
// Should be used when we know that not all fields responses are present
|
||||
// - Can happen when we are parsing the prefill query string
|
||||
// - Can happen when we are parsing a booking's responses (which was created before we added a new required field)
|
||||
export default function getBookingResponsesSchema({ eventType, view }: { eventType: EventType; view: View }) {
|
||||
export default function getBookingResponsesSchema({ bookingFields, view }: CommonParams) {
|
||||
const schema = bookingResponses.and(z.record(z.any()));
|
||||
return preprocess({ schema, eventType, isPartialSchema: false, view });
|
||||
return preprocess({ schema, bookingFields, isPartialSchema: false, view });
|
||||
}
|
||||
|
||||
// TODO: Move preprocess of `booking.responses` to FormBuilder schema as that is going to parse the fields supported by FormBuilder
|
||||
// It allows anyone using FormBuilder to get the same preprocessing automatically
|
||||
function preprocess<T extends z.ZodType>({
|
||||
schema,
|
||||
eventType,
|
||||
bookingFields,
|
||||
isPartialSchema,
|
||||
view: currentView,
|
||||
}: {
|
||||
}: CommonParams & {
|
||||
schema: T;
|
||||
// It is useful when we want to prefill the responses with the partial values. Partial can be in 2 ways
|
||||
// - Not all required fields are need to be provided for prefill.
|
||||
// - Even a field response itself can be partial so the content isn't validated e.g. a field with type="phone" can be given a partial phone number(e.g. Specifying the country code like +91)
|
||||
isPartialSchema: boolean;
|
||||
eventType: {
|
||||
bookingFields: (z.infer<typeof eventTypeBookingFields> & z.BRAND<"HAS_SYSTEM_FIELDS">) | null;
|
||||
};
|
||||
view: View;
|
||||
}): z.ZodType<z.infer<T>, z.infer<T>, z.infer<T>> {
|
||||
const preprocessed = z.preprocess(
|
||||
(responses) => {
|
||||
const parsedResponses = z.record(z.any()).nullable().parse(responses) || {};
|
||||
const newResponses = {} as typeof parsedResponses;
|
||||
// if eventType has been deleted, we won't have bookingFields and thus we can't preprocess or validate them.
|
||||
if (!eventType.bookingFields) return parsedResponses;
|
||||
eventType.bookingFields.forEach((field) => {
|
||||
if (!bookingFields) return parsedResponses;
|
||||
bookingFields.forEach((field) => {
|
||||
const value = parsedResponses[field.name];
|
||||
if (value === undefined) {
|
||||
// If there is no response for the field, then we don't need to do any processing
|
||||
@@ -110,11 +101,11 @@ function preprocess<T extends z.ZodType>({
|
||||
};
|
||||
},
|
||||
schema.superRefine(async (responses, ctx) => {
|
||||
if (!eventType.bookingFields) {
|
||||
if (!bookingFields) {
|
||||
// if eventType has been deleted, we won't have bookingFields and thus we can't validate the responses.
|
||||
return;
|
||||
}
|
||||
for (const bookingField of eventType.bookingFields) {
|
||||
for (const bookingField of bookingFields) {
|
||||
const value = responses[bookingField.name];
|
||||
const stringSchema = z.string();
|
||||
const emailSchema = isPartialSchema ? z.string() : z.string().refine(emailSchemaRefinement);
|
||||
|
||||
@@ -43,7 +43,7 @@ export const getCalEventResponses = ({
|
||||
const label = field.label || field.defaultLabel;
|
||||
if (!label) {
|
||||
//TODO: This error must be thrown while saving event-type as well so that such an event-type can't be saved
|
||||
throw new Error('Missing label for booking field "' + field.name + '"');
|
||||
throw new Error(`Missing label for booking field "${field.name}"`);
|
||||
}
|
||||
|
||||
// If the guests field is hidden (disableGuests is set on the event type) don't try and infer guests from attendees list
|
||||
|
||||
@@ -591,19 +591,16 @@ async function getOriginalRescheduledBooking(uid: string, seatsEventType?: boole
|
||||
});
|
||||
}
|
||||
|
||||
export async function getBookingData({
|
||||
export async function getBookingData<T extends z.ZodType>({
|
||||
req,
|
||||
isNotAnApiCall,
|
||||
eventType,
|
||||
schema,
|
||||
}: {
|
||||
req: NextApiRequest;
|
||||
isNotAnApiCall: boolean;
|
||||
eventType: Awaited<ReturnType<typeof getEventTypesFromDB>>;
|
||||
schema: T;
|
||||
}) {
|
||||
const bookingDataSchema = getBookingDataSchema(req.body?.rescheduleUid, isNotAnApiCall, eventType);
|
||||
|
||||
const reqBody = await bookingDataSchema.parseAsync(req.body);
|
||||
|
||||
const reqBody = await schema.parseAsync(req.body);
|
||||
const reqBodyWithEnd = (reqBody: ReqBodyWithoutEnd): reqBody is ReqBodyWithEnd => {
|
||||
// Use the event length to auto-set the event end time.
|
||||
if (!Object.prototype.hasOwnProperty.call(reqBody, "end")) {
|
||||
@@ -615,11 +612,9 @@ export async function getBookingData({
|
||||
throw new Error(ErrorCode.RequestBodyWithouEnd);
|
||||
}
|
||||
// reqBody.end is no longer an optional property.
|
||||
if ("customInputs" in reqBody) {
|
||||
if (reqBody.customInputs) {
|
||||
// Check if required custom inputs exist
|
||||
handleCustomInputs(eventType.customInputs as EventTypeCustomInput[], reqBody.customInputs);
|
||||
}
|
||||
if (reqBody.customInputs) {
|
||||
// Check if required custom inputs exist
|
||||
handleCustomInputs(eventType.customInputs as EventTypeCustomInput[], reqBody.customInputs);
|
||||
const reqBodyWithLegacyProps = bookingCreateSchemaLegacyPropsForApi.parse(reqBody);
|
||||
return {
|
||||
...reqBody,
|
||||
@@ -630,31 +625,36 @@ export async function getBookingData({
|
||||
smsReminderNumber: reqBodyWithLegacyProps.smsReminderNumber,
|
||||
notes: reqBodyWithLegacyProps.notes,
|
||||
rescheduleReason: reqBodyWithLegacyProps.rescheduleReason,
|
||||
};
|
||||
} else {
|
||||
if (!reqBody.responses) {
|
||||
throw new Error("`responses` must not be nullish");
|
||||
}
|
||||
const responses = reqBody.responses;
|
||||
|
||||
const { userFieldsResponses: calEventUserFieldsResponses, responses: calEventResponses } =
|
||||
getCalEventResponses({
|
||||
bookingFields: eventType.bookingFields,
|
||||
responses,
|
||||
});
|
||||
return {
|
||||
...reqBody,
|
||||
name: responses.name,
|
||||
email: responses.email,
|
||||
guests: responses.guests ? responses.guests : [],
|
||||
location: responses.location?.optionValue || responses.location?.value || "",
|
||||
smsReminderNumber: responses.smsReminderNumber,
|
||||
notes: responses.notes || "",
|
||||
calEventUserFieldsResponses,
|
||||
rescheduleReason: responses.rescheduleReason,
|
||||
calEventResponses,
|
||||
// So TS doesn't complain about unknown properties
|
||||
calEventUserFieldsResponses: undefined,
|
||||
calEventResponses: undefined,
|
||||
customInputs: undefined,
|
||||
};
|
||||
}
|
||||
if (!reqBody.responses) {
|
||||
throw new Error("`responses` must not be nullish");
|
||||
}
|
||||
const responses = reqBody.responses;
|
||||
|
||||
const { userFieldsResponses: calEventUserFieldsResponses, responses: calEventResponses } =
|
||||
getCalEventResponses({
|
||||
bookingFields: eventType.bookingFields,
|
||||
responses,
|
||||
});
|
||||
return {
|
||||
...reqBody,
|
||||
name: responses.name,
|
||||
email: responses.email,
|
||||
guests: responses.guests ? responses.guests : [],
|
||||
location: responses.location?.optionValue || responses.location?.value || "",
|
||||
smsReminderNumber: responses.smsReminderNumber,
|
||||
notes: responses.notes || "",
|
||||
calEventUserFieldsResponses,
|
||||
rescheduleReason: responses.rescheduleReason,
|
||||
calEventResponses,
|
||||
// So TS doesn't complain about unknown properties
|
||||
customInputs: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async function createBooking({
|
||||
@@ -841,13 +841,10 @@ export function getCustomInputsResponses(
|
||||
eventTypeCustomInputs: Awaited<ReturnType<typeof getEventTypesFromDB>>["customInputs"]
|
||||
) {
|
||||
const customInputsResponses = {} as NonNullable<CalendarEvent["customInputs"]>;
|
||||
if ("customInputs" in reqBody) {
|
||||
const reqCustomInputsResponses = reqBody.customInputs || [];
|
||||
if (reqCustomInputsResponses?.length > 0) {
|
||||
reqCustomInputsResponses.forEach(({ label, value }) => {
|
||||
customInputsResponses[label] = value;
|
||||
});
|
||||
}
|
||||
if (reqBody.customInputs && (reqBody.customInputs.length || 0) > 0) {
|
||||
reqBody.customInputs.forEach(({ label, value }) => {
|
||||
customInputsResponses[label] = value;
|
||||
});
|
||||
} else {
|
||||
const responses = reqBody.responses || {};
|
||||
// Backward Compatibility: Map new `responses` to old `customInputs` format so that webhooks can still receive same values.
|
||||
@@ -994,15 +991,13 @@ export const findBookingQuery = async (bookingId: number) => {
|
||||
return foundBooking;
|
||||
};
|
||||
|
||||
type BookingDataSchemaGetter =
|
||||
| typeof getBookingDataSchema
|
||||
| typeof import("@calcom/features/bookings/lib/getBookingDataSchemaForApi").default;
|
||||
|
||||
async function handler(
|
||||
req: NextApiRequest & { userId?: number | undefined },
|
||||
{
|
||||
isNotAnApiCall = false,
|
||||
}: {
|
||||
isNotAnApiCall?: boolean;
|
||||
} = {
|
||||
isNotAnApiCall: false,
|
||||
}
|
||||
bookingDataSchemaGetter: BookingDataSchemaGetter = getBookingDataSchema
|
||||
) {
|
||||
const { userId } = req;
|
||||
|
||||
@@ -1016,6 +1011,17 @@ async function handler(
|
||||
...eventType,
|
||||
bookingFields: getBookingFieldsWithSystemFields(eventType),
|
||||
};
|
||||
|
||||
const bookingDataSchema = bookingDataSchemaGetter({
|
||||
view: req.body?.rescheduleUid ? "reschedule" : "booking",
|
||||
bookingFields: eventType.bookingFields,
|
||||
});
|
||||
const bookingData = await getBookingData({
|
||||
req,
|
||||
eventType,
|
||||
schema: bookingDataSchema,
|
||||
});
|
||||
|
||||
const {
|
||||
recurringCount,
|
||||
noEmail,
|
||||
@@ -1033,11 +1039,7 @@ async function handler(
|
||||
rescheduleReason,
|
||||
luckyUsers,
|
||||
...reqBody
|
||||
} = await getBookingData({
|
||||
req,
|
||||
isNotAnApiCall,
|
||||
eventType,
|
||||
});
|
||||
} = bookingData;
|
||||
|
||||
const loggerWithEventDetails = createLoggerWithEventDetails(eventTypeId, reqBody.user, eventTypeSlug);
|
||||
|
||||
@@ -1199,7 +1201,10 @@ async function handler(
|
||||
Object.prototype.hasOwnProperty.call(eventType, "durationLimits")
|
||||
) {
|
||||
const startAsDate = dayjs(reqBody.start).toDate();
|
||||
if (eventType.bookingLimits) {
|
||||
if (
|
||||
eventType.bookingLimits &&
|
||||
/* Empty object is truthy */ Object.keys(eventType.bookingLimits).length > 0
|
||||
) {
|
||||
await checkBookingLimits(
|
||||
eventType.bookingLimits as IntervalLimit,
|
||||
startAsDate,
|
||||
@@ -1507,7 +1512,7 @@ async function handler(
|
||||
|
||||
const attendeesList = [...invitee, ...guests];
|
||||
|
||||
const responses = "responses" in reqBody ? reqBody.responses : null;
|
||||
const responses = reqBody.responses || null;
|
||||
|
||||
const evtName = !eventType?.isDynamic ? eventType.eventName : responses?.title;
|
||||
const eventNameObject = {
|
||||
@@ -1524,9 +1529,6 @@ async function handler(
|
||||
t: tOrganizer,
|
||||
};
|
||||
|
||||
const calEventUserFieldsResponses =
|
||||
"calEventUserFieldsResponses" in reqBody ? reqBody.calEventUserFieldsResponses : null;
|
||||
|
||||
const iCalUID = getICalUID({
|
||||
event: { iCalUID: originalRescheduledBooking?.iCalUID, uid: originalRescheduledBooking?.uid },
|
||||
uid,
|
||||
@@ -1563,8 +1565,8 @@ async function handler(
|
||||
language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" },
|
||||
timeFormat: getTimeFormatStringFromUserTimeFormat(organizerUser.timeFormat),
|
||||
},
|
||||
responses: "calEventResponses" in reqBody ? reqBody.calEventResponses : null,
|
||||
userFieldsResponses: calEventUserFieldsResponses,
|
||||
responses: reqBody.calEventResponses || null,
|
||||
userFieldsResponses: reqBody.calEventUserFieldsResponses || null,
|
||||
attendees: attendeesList,
|
||||
location: bookingLocation, // Will be processed by the EventManager later.
|
||||
conferenceCredentialId,
|
||||
|
||||
@@ -6,11 +6,12 @@ import { v5 as uuidv5 } from "uuid";
|
||||
|
||||
import { createInstantMeetingWithCalVideo } from "@calcom/core/videoClient";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import getBookingDataSchema from "@calcom/features/bookings/lib/getBookingDataSchema";
|
||||
import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/getBookingFields";
|
||||
import {
|
||||
getEventTypesFromDB,
|
||||
getBookingData,
|
||||
getCustomInputsResponses,
|
||||
getEventTypesFromDB,
|
||||
} from "@calcom/features/bookings/lib/handleNewBooking";
|
||||
import { getFullName } from "@calcom/features/form-builder/utils";
|
||||
import { sendGenericWebhookPayload } from "@calcom/features/webhooks/lib/sendPayload";
|
||||
@@ -83,10 +84,14 @@ async function handler(req: NextApiRequest) {
|
||||
throw new Error("Only Team Event Types are supported for Instant Meeting");
|
||||
}
|
||||
|
||||
const schema = getBookingDataSchema({
|
||||
view: req.body?.rescheduleUid ? "reschedule" : "booking",
|
||||
bookingFields: eventType.bookingFields,
|
||||
});
|
||||
const reqBody = await getBookingData({
|
||||
req,
|
||||
isNotAnApiCall: true,
|
||||
eventType,
|
||||
schema,
|
||||
});
|
||||
const { email: bookerEmail, name: bookerName } = reqBody;
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@ import type { Prisma } from "@prisma/client";
|
||||
import type { UnitTypeLongPlural } from "dayjs";
|
||||
import type { TFunction } from "next-i18next";
|
||||
import z, { ZodNullable, ZodObject, ZodOptional } from "zod";
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import type {
|
||||
AnyZodObject,
|
||||
objectInputType,
|
||||
@@ -274,6 +272,7 @@ export const extendedBookingCreateBody = bookingCreateBodySchema.merge(
|
||||
)
|
||||
.optional(),
|
||||
luckyUsers: z.array(z.number()).optional(),
|
||||
customInputs: z.undefined().optional(),
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
+6
-2
@@ -35,8 +35,12 @@ const workspaces = packagedEmbedTestsOnly
|
||||
{
|
||||
test: {
|
||||
include: ["packages/**/*.{test,spec}.{ts,js}", "apps/**/*.{test,spec}.{ts,js}"],
|
||||
// TODO: Ignore the api until tests are fixed
|
||||
exclude: ["**/node_modules/**/*", "packages/embeds/**/*", "packages/lib/hooks/**/*"],
|
||||
exclude: [
|
||||
"**/node_modules/**/*",
|
||||
"**/.next/**/*",
|
||||
"packages/embeds/**/*",
|
||||
"packages/lib/hooks/**/*",
|
||||
],
|
||||
setupFiles: ["setupVitest.ts"],
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user