From 95b49a59951aa3c97c15165165dd2f9ad736d768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Tue, 5 Oct 2021 16:46:48 -0600 Subject: [PATCH] Several type fixes (#855) * Several type fixes * Update ee/lib/stripe/client.ts Co-authored-by: Alex Johansson * Typo * Refactors createPaymentLink * Simplify calendarClietn type Co-authored-by: Alex Johansson Co-authored-by: Peer Richelsen Co-authored-by: Alex van Andel --- components/booking/pages/BookingPage.tsx | 7 ++++++- ee/lib/stripe/client.ts | 9 ++++++++- ee/lib/stripe/server.ts | 17 ++++++++--------- lib/calendarClient.ts | 7 ++----- lib/types/utils.ts | 5 +++++ pages/api/book/event.ts | 16 ++++++++-------- 6 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 lib/types/utils.ts diff --git a/components/booking/pages/BookingPage.tsx b/components/booking/pages/BookingPage.tsx index 74395813..05ad3b96 100644 --- a/components/booking/pages/BookingPage.tsx +++ b/components/booking/pages/BookingPage.tsx @@ -159,7 +159,12 @@ const BookingPage = (props: BookingPageProps) => { let successUrl = `/success?${query}`; if (content?.paymentUid) { - successUrl = createPaymentLink(content?.paymentUid, payload.name, date, false); + successUrl = createPaymentLink({ + paymentUid: content?.paymentUid, + name: payload.name, + date, + absolute: false, + }); } await router.push(successUrl); diff --git a/ee/lib/stripe/client.ts b/ee/lib/stripe/client.ts index 3cc96191..f56e6900 100644 --- a/ee/lib/stripe/client.ts +++ b/ee/lib/stripe/client.ts @@ -1,4 +1,5 @@ import { loadStripe, Stripe } from "@stripe/stripe-js"; +import { Maybe } from "@trpc/server"; import { stringify } from "querystring"; const stripePublicKey = process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY!; @@ -18,7 +19,13 @@ const getStripe = (userPublicKey?: string) => { return stripePromise; }; -export function createPaymentLink(paymentUid: string, name?: string, date?: string, absolute = true): string { +export function createPaymentLink(opts: { + paymentUid: string; + name?: Maybe; + date?: Maybe; + absolute?: boolean; +}): string { + const { paymentUid, name, date, absolute = true } = opts; let link = ""; if (absolute) link = process.env.NEXT_PUBLIC_APP_URL!; const query = stringify({ date, name }); diff --git a/ee/lib/stripe/server.ts b/ee/lib/stripe/server.ts index 29167172..f961324c 100644 --- a/ee/lib/stripe/server.ts +++ b/ee/lib/stripe/server.ts @@ -3,7 +3,7 @@ import Stripe from "stripe"; import { JsonValue } from "type-fest"; import { v4 as uuidv4 } from "uuid"; -import { CalendarEvent, Person } from "@lib/calendarClient"; +import { CalendarEvent } from "@lib/calendarClient"; import EventOrganizerRefundFailedMail from "@lib/emails/EventOrganizerRefundFailedMail"; import EventPaymentMail from "@lib/emails/EventPaymentMail"; import prisma from "@lib/prisma"; @@ -35,19 +35,14 @@ export async function handlePayment( }, stripeCredential: { key: JsonValue }, booking: { - user: { email: string; name: string; timeZone: string }; + user: { email: string | null; name: string | null; timeZone: string } | null; id: number; - title: string; - description: string; startTime: { toISOString: () => string }; - endTime: { toISOString: () => string }; - attendees: Person[]; - location?: string; uid: string; } ) { const paymentFee = Math.round( - selectedEventType.price * parseFloat(paymentFeePercentage || "0") + parseInt(paymentFeeFixed || "0") + selectedEventType.price * parseFloat(`${paymentFeePercentage}`) + parseInt(`${paymentFeeFixed}`) ); const { stripe_user_id, stripe_publishable_key } = stripeCredential.key as Stripe.OAuthToken; @@ -79,7 +74,11 @@ export async function handlePayment( }); const mail = new EventPaymentMail( - createPaymentLink(payment.uid, booking.user.name, booking.startTime.toISOString()), + createPaymentLink({ + paymentUid: payment.uid, + name: booking.user?.name, + date: booking.startTime.toISOString(), + }), evt, booking.uid ); diff --git a/lib/calendarClient.ts b/lib/calendarClient.ts index 4778e13d..ef43eae0 100644 --- a/lib/calendarClient.ts +++ b/lib/calendarClient.ts @@ -1,4 +1,4 @@ -import { Prisma, Credential } from "@prisma/client"; +import { Credential } from "@prisma/client"; import { EventResult } from "@lib/events/EventManager"; import logger from "@lib/logger"; @@ -110,10 +110,7 @@ const o365Auth = (credential) => { }; }; -const userData = Prisma.validator()({ - select: { name: true, email: true, timeZone: true }, -}); -export type Person = Prisma.UserGetPayload; +export type Person = { name: string; email: string; timeZone: string }; export interface CalendarEvent { type: string; diff --git a/lib/types/utils.ts b/lib/types/utils.ts new file mode 100644 index 00000000..718c55eb --- /dev/null +++ b/lib/types/utils.ts @@ -0,0 +1,5 @@ +export type RequiredNotNull = { + [P in keyof T]: NonNullable; +}; + +export type Ensure = T & RequiredNotNull>; diff --git a/pages/api/book/event.ts b/pages/api/book/event.ts index c0aca847..954cff23 100644 --- a/pages/api/book/event.ts +++ b/pages/api/book/event.ts @@ -239,8 +239,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const teamMembers = eventType.schedulingType === SchedulingType.COLLECTIVE ? users.slice(1).map((user) => ({ - email: user.email, - name: user.name, + email: user.email || "", + name: user.name || "", timeZone: user.timeZone, })) : []; @@ -257,8 +257,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) startTime: reqBody.start, endTime: reqBody.end, organizer: { - name: users[0].name, - email: users[0].email, + name: users[0].name || "Nameless", + email: users[0].email || "Email-less", timeZone: users[0].timeZone, }, attendees: attendeesList, @@ -328,6 +328,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) let referencesToCreate: PartialReference[] = []; type User = Prisma.UserGetPayload; let user: User | null = null; + for (const currentUser of users) { if (!currentUser) { console.error(`currentUser not found`); @@ -404,6 +405,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) } } } + + if (!user) throw Error("Can't continue, user not found."); + // After polling videoBusyTimes, credentials might have been changed due to refreshment, so query them again. const eventManager = new EventManager(await refreshCredentials(user.credentials)); @@ -446,11 +450,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) if (typeof eventType.price === "number" && eventType.price > 0) { try { const [firstStripeCredential] = user.credentials.filter((cred) => cred.type == "stripe_payment"); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - /* @ts-ignore https://github.com/prisma/prisma/issues/9389 */ if (!booking.user) booking.user = user; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - /* @ts-ignore https://github.com/prisma/prisma/issues/9389 */ const payment = await handlePayment(evt, eventType, firstStripeCredential, booking); res.status(201).json({ ...booking, message: "Payment required", paymentUid: payment.uid });