From 54b7c5570053b0f67123fae27a54cb4468520e64 Mon Sep 17 00:00:00 2001 From: exception Date: Fri, 16 Feb 2024 14:31:21 -0300 Subject: [PATCH 01/13] chore: Refactor feature flags --- apps/web/lib/insights/getServerSideProps.tsx | 6 +++--- .../settings/organizations/new/getServerSideProps.tsx | 6 +++--- apps/web/lib/signup/getServerSideProps.tsx | 6 +++--- apps/web/lib/team/[slug]/getServerSideProps.tsx | 9 ++++----- .../app-store/googlecalendar/lib/CalendarService.ts | 6 +++--- packages/emails/templates/_base-email.ts | 6 +++--- packages/features/auth/lib/verifyEmail.ts | 10 +++++----- .../features/ee/organizations/pages/organization.tsx | 6 +++--- packages/features/flags/server/utils.ts | 11 +++++++++++ .../routers/loggedInViewer/updateProfile.handler.ts | 8 +++----- 10 files changed, 41 insertions(+), 33 deletions(-) diff --git a/apps/web/lib/insights/getServerSideProps.tsx b/apps/web/lib/insights/getServerSideProps.tsx index d89a77bd5028d0..a6108e44ac2392 100644 --- a/apps/web/lib/insights/getServerSideProps.tsx +++ b/apps/web/lib/insights/getServerSideProps.tsx @@ -1,11 +1,11 @@ -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; // If feature flag is disabled, return not found on getServerSideProps export const getServerSideProps = async () => { const prisma = await import("@calcom/prisma").then((mod) => mod.default); - const flags = await getFeatureFlagMap(prisma); + const insightsEnabled = await getFeatureFlag(prisma, "insights"); - if (flags.insights === false) { + if (!insightsEnabled) { return { notFound: true, } as const; diff --git a/apps/web/lib/settings/organizations/new/getServerSideProps.tsx b/apps/web/lib/settings/organizations/new/getServerSideProps.tsx index 5ba051296de736..f54bfc2f424d03 100644 --- a/apps/web/lib/settings/organizations/new/getServerSideProps.tsx +++ b/apps/web/lib/settings/organizations/new/getServerSideProps.tsx @@ -1,12 +1,12 @@ import type { GetServerSidePropsContext } from "next"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; export const getServerSideProps = async (context: GetServerSidePropsContext) => { const prisma = await import("@calcom/prisma").then((mod) => mod.default); - const flags = await getFeatureFlagMap(prisma); + const organizations = await getFeatureFlag(prisma, "organizations"); // Check if organizations are enabled - if (flags["organizations"] !== true) { + if (!organizations) { return { notFound: true, } as const; diff --git a/apps/web/lib/signup/getServerSideProps.tsx b/apps/web/lib/signup/getServerSideProps.tsx index da32a050c0c9ce..22a2149a9f05b1 100644 --- a/apps/web/lib/signup/getServerSideProps.tsx +++ b/apps/web/lib/signup/getServerSideProps.tsx @@ -4,7 +4,7 @@ import { z } from "zod"; import { getOrgUsernameFromEmail } from "@calcom/features/auth/signup/utils/getOrgUsernameFromEmail"; import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiumUsername"; import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; import { IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants"; import slugify from "@calcom/lib/slugify"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; @@ -24,7 +24,7 @@ const querySchema = z.object({ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { const prisma = await import("@calcom/prisma").then((mod) => mod.default); - const flags = await getFeatureFlagMap(prisma); + const signupDisabled = await getFeatureFlag(prisma, "disable-signup"); const ssr = await ssrInit(ctx); const token = z.string().optional().parse(ctx.query.token); @@ -38,7 +38,7 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { // username + email prepopulated from query params const { username: preFillusername, email: prefilEmail } = querySchema.parse(ctx.query); - if ((process.env.NEXT_PUBLIC_DISABLE_SIGNUP === "true" && !token) || flags["disable-signup"]) { + if ((process.env.NEXT_PUBLIC_DISABLE_SIGNUP === "true" && !token) || signupDisabled) { return { notFound: true, } as const; diff --git a/apps/web/lib/team/[slug]/getServerSideProps.tsx b/apps/web/lib/team/[slug]/getServerSideProps.tsx index 76967e87c223f7..fa68d09675092c 100644 --- a/apps/web/lib/team/[slug]/getServerSideProps.tsx +++ b/apps/web/lib/team/[slug]/getServerSideProps.tsx @@ -1,7 +1,7 @@ import type { GetServerSidePropsContext } from "next"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client"; import logger from "@calcom/lib/logger"; import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; @@ -37,12 +37,11 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => // Provided by Rewrite from next.config.js const isOrgProfile = context.query?.isOrgProfile === "1"; - const flags = await getFeatureFlagMap(prisma); - const isOrganizationFeatureEnabled = flags["organizations"]; + const organizationsEnabled = await getFeatureFlag(prisma, "organizations"); log.debug("getServerSideProps", { isOrgProfile, - isOrganizationFeatureEnabled, + isOrganizationFeatureEnabled: organizationsEnabled, isValidOrgDomain, currentOrgDomain, }); @@ -74,7 +73,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => if ( (!isValidOrgDomain && team?.parent) || (!isValidOrgDomain && !!metadata?.isOrganization) || - !isOrganizationFeatureEnabled + !organizationsEnabled ) { return { notFound: true } as const; } diff --git a/packages/app-store/googlecalendar/lib/CalendarService.ts b/packages/app-store/googlecalendar/lib/CalendarService.ts index 079a9c420af4d3..3ce9a8fa1b7f68 100644 --- a/packages/app-store/googlecalendar/lib/CalendarService.ts +++ b/packages/app-store/googlecalendar/lib/CalendarService.ts @@ -6,7 +6,7 @@ import { RRule } from "rrule"; import { MeetLocationType } from "@calcom/app-store/locations"; import dayjs from "@calcom/dayjs"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; import { getLocation, getRichDescription } from "@calcom/lib/CalEventParser"; import type CalendarService from "@calcom/lib/CalendarService"; import logger from "@calcom/lib/logger"; @@ -461,10 +461,10 @@ export default class GoogleCalendarService implements Calendar { items: { id: string }[]; }): Promise { const calendar = await this.authedCalendar(); - const flags = await getFeatureFlagMap(prisma); + const calendarCacheEnabled = await getFeatureFlag(prisma, "calendar-cache"); let freeBusyResult: calendar_v3.Schema$FreeBusyResponse = {}; - if (!flags["calendar-cache"]) { + if (!calendarCacheEnabled) { this.log.warn("Calendar Cache is disabled - Skipping"); const { timeMin, timeMax, items } = args; const apires = await calendar.freebusy.query({ diff --git a/packages/emails/templates/_base-email.ts b/packages/emails/templates/_base-email.ts index 0fd65be9d76361..790f4b9210b32b 100644 --- a/packages/emails/templates/_base-email.ts +++ b/packages/emails/templates/_base-email.ts @@ -3,7 +3,7 @@ import { createTransport } from "nodemailer"; import { z } from "zod"; import dayjs from "@calcom/dayjs"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; import { getErrorFromUnknown } from "@calcom/lib/errors"; import { serverConfig } from "@calcom/lib/serverConfig"; import { setTestEmail } from "@calcom/lib/testEmails"; @@ -28,9 +28,9 @@ export default class BaseEmail { return {}; } public async sendEmail() { - const featureFlags = await getFeatureFlagMap(prisma); + const emailsDisabled = await getFeatureFlag(prisma, "emails"); /** If email kill switch exists and is active, we prevent emails being sent. */ - if (featureFlags.emails) { + if (emailsDisabled) { console.warn("Skipped Sending Email due to active Kill Switch"); return new Promise((r) => r("Skipped Sending Email due to active Kill Switch")); } diff --git a/packages/features/auth/lib/verifyEmail.ts b/packages/features/auth/lib/verifyEmail.ts index 10bf7b35cd08ab..0f508181709d5f 100644 --- a/packages/features/auth/lib/verifyEmail.ts +++ b/packages/features/auth/lib/verifyEmail.ts @@ -6,7 +6,7 @@ import { sendEmailVerificationLink, sendChangeOfEmailVerificationLink, } from "@calcom/emails/email-manager"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import { WEBAPP_URL } from "@calcom/lib/constants"; import logger from "@calcom/lib/logger"; @@ -24,9 +24,9 @@ interface VerifyEmailType { export const sendEmailVerification = async ({ email, language, username }: VerifyEmailType) => { const token = randomBytes(32).toString("hex"); const translation = await getTranslation(language ?? "en", "common"); - const flags = await getFeatureFlagMap(prisma); + const emailVerification = await getFeatureFlag(prisma, "email-verification"); - if (!flags["email-verification"]) { + if (!emailVerification) { log.warn("Email verification is disabled - Skipping"); return { ok: true, skipped: true }; } @@ -93,9 +93,9 @@ interface ChangeOfEmail { export const sendChangeOfEmailVerification = async ({ user, language }: ChangeOfEmail) => { const token = randomBytes(32).toString("hex"); const translation = await getTranslation(language ?? "en", "common"); - const flags = await getFeatureFlagMap(prisma); + const emailVerification = await getFeatureFlag(prisma, "email-verification"); - if (!flags["email-verification"]) { + if (!emailVerification) { log.warn("Email verification is disabled - Skipping"); return { ok: true, skipped: true }; } diff --git a/packages/features/ee/organizations/pages/organization.tsx b/packages/features/ee/organizations/pages/organization.tsx index b9114d70da1ae7..55dd42a061c184 100644 --- a/packages/features/ee/organizations/pages/organization.tsx +++ b/packages/features/ee/organizations/pages/organization.tsx @@ -1,14 +1,14 @@ import type { GetServerSidePropsContext } from "next"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; import { MembershipRole } from "@calcom/prisma/client"; export const getServerSideProps = async ({ req, res }: GetServerSidePropsContext) => { const prisma = await import("@calcom/prisma").then((mod) => mod.default); - const flags = await getFeatureFlagMap(prisma); + const organizationsEnabled = await getFeatureFlag(prisma, "orgnizations"); // Check if organizations are enabled - if (flags["organizations"] !== true) { + if (!organizationsEnabled) { return { notFound: true, }; diff --git a/packages/features/flags/server/utils.ts b/packages/features/flags/server/utils.ts index ddbf1dc491b32f..fe68c00d3fb883 100644 --- a/packages/features/flags/server/utils.ts +++ b/packages/features/flags/server/utils.ts @@ -12,3 +12,14 @@ export async function getFeatureFlagMap(prisma: PrismaClient) { return acc; }, {} as Partial); } + +export const getFeatureFlag = async (prisma: PrismaClient, slug: keyof AppFlags): Promise => { + const flag = await prisma.feature.findUnique({ + where: { + slug, + }, + cacheStrategy: { swr: 300, ttl: 300 }, + }); + + return Boolean(flag && flag.enabled); +}; diff --git a/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts b/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts index 0f0a444b054903..75f262b34472ca 100644 --- a/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts +++ b/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts @@ -6,7 +6,7 @@ import stripe from "@calcom/app-store/stripepayment/lib/server"; import { getPremiumMonthlyPlanPriceId } from "@calcom/app-store/stripepayment/lib/utils"; import { passwordResetRequest } from "@calcom/features/auth/lib/passwordResetRequest"; import { sendChangeOfEmailVerification } from "@calcom/features/auth/lib/verifyEmail"; -import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; +import { getFeatureFlag } from "@calcom/features/flags/server/utils"; import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; @@ -63,7 +63,7 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions) const { user } = ctx; const userMetadata = handleUserMetadata({ ctx, input }); const locale = input.locale || user.locale; - const flags = await getFeatureFlagMap(prisma); + const emailVerification = await getFeatureFlag(prisma, "email-verification"); const data: Prisma.UserUpdateInput = { ...input, @@ -135,10 +135,8 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions) hasEmailBeenChanged && user.identityProvider !== IdentityProvider.CAL; const hasEmailChangedOnCalProvider = hasEmailBeenChanged && user.identityProvider === IdentityProvider.CAL; - const sendEmailVerification = flags["email-verification"]; - if (hasEmailBeenChanged) { - if (sendEmailVerification && hasEmailChangedOnCalProvider) { + if (emailVerification && hasEmailChangedOnCalProvider) { // Set metadata of the user so we can set it to this updated email once it is confirmed data.metadata = { ...userMetadata, From 6460577580cedb99994fa419e3bc1f4f611f5a4e Mon Sep 17 00:00:00 2001 From: exception Date: Fri, 16 Feb 2024 17:26:27 -0300 Subject: [PATCH 02/13] chore: remove accelarate flags --- packages/features/flags/server/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/features/flags/server/utils.ts b/packages/features/flags/server/utils.ts index fe68c00d3fb883..84c664daf1e63b 100644 --- a/packages/features/flags/server/utils.ts +++ b/packages/features/flags/server/utils.ts @@ -18,7 +18,6 @@ export const getFeatureFlag = async (prisma: PrismaClient, slug: keyof AppFlags) where: { slug, }, - cacheStrategy: { swr: 300, ttl: 300 }, }); return Boolean(flag && flag.enabled); From 63fb23d056ec4aba3bcfe8aa99270599ecf52ba8 Mon Sep 17 00:00:00 2001 From: exception Date: Fri, 16 Feb 2024 17:34:03 -0300 Subject: [PATCH 03/13] chore: temp cache --- packages/features/flags/server/utils.ts | 29 ++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/features/flags/server/utils.ts b/packages/features/flags/server/utils.ts index 84c664daf1e63b..72410bb93836a4 100644 --- a/packages/features/flags/server/utils.ts +++ b/packages/features/flags/server/utils.ts @@ -13,12 +13,39 @@ export async function getFeatureFlagMap(prisma: PrismaClient) { }, {} as Partial); } +interface CacheEntry { + value: boolean; // adapt to other supported value types in the future + expiry: number; +} + +const featureFlagCache = new Map(); + +const isExpired = (entry: CacheEntry): boolean => { + return Date.now() > entry.expiry; +}; + export const getFeatureFlag = async (prisma: PrismaClient, slug: keyof AppFlags): Promise => { + const cacheEntry = featureFlagCache.get(slug); + + // Check if the flag is in the cache and not expired + if (cacheEntry && !isExpired(cacheEntry)) { + return cacheEntry.value; + } + + // Fetch from the database if not in cache or cache is expired const flag = await prisma.feature.findUnique({ where: { slug, }, }); - return Boolean(flag && flag.enabled); + const isEnabled = Boolean(flag && flag.enabled); + + // Calculate expiry time (current time + 5 minutes) + const expiry = Date.now() + 5 * 60 * 1000; // 5 minutes in milliseconds + + // Store the flag in the cache with its expiry time + featureFlagCache.set(slug, { value: isEnabled, expiry }); + + return isEnabled; }; From d81b708be363903e7fc2ce15bdeec081cb2a6fdf Mon Sep 17 00:00:00 2001 From: exception Date: Fri, 16 Feb 2024 17:49:27 -0300 Subject: [PATCH 04/13] chore: optns --- .../controllers/slots.controller.e2e-spec.ts | 28 + packages/features/flags/server/utils.ts | 13 +- packages/kysely/types.ts | 866 ++++++++++++++++++ 3 files changed, 904 insertions(+), 3 deletions(-) create mode 100644 apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts create mode 100644 packages/kysely/types.ts diff --git a/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts b/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts new file mode 100644 index 00000000000000..d1022bcf313194 --- /dev/null +++ b/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts @@ -0,0 +1,28 @@ +import { bootstrap } from "@/app"; +import { AppModule } from "@/app.module"; +import { HttpExceptionFilter } from "@/filters/http-exception.filter"; +import { PrismaExceptionFilter } from "@/filters/prisma-exception.filter"; +import { SlotsModule } from "@/modules/slots/slots.module"; +import type { INestApplication } from "@nestjs/common"; +import type { NestExpressApplication } from "@nestjs/platform-express"; +import { Test } from "@nestjs/testing"; + +describe("Platform Slots e2e", () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [PrismaExceptionFilter, HttpExceptionFilter], + imports: [AppModule, SlotsModule], + }).compile(); + + app = moduleRef.createNestApplication(); + bootstrap(app as NestExpressApplication); + + await app.init(); + }); + + it("should be defined", () => { + expect(app).toBeDefined(); + }); +}); diff --git a/packages/features/flags/server/utils.ts b/packages/features/flags/server/utils.ts index 72410bb93836a4..25bc16eee1425b 100644 --- a/packages/features/flags/server/utils.ts +++ b/packages/features/flags/server/utils.ts @@ -18,13 +18,21 @@ interface CacheEntry { expiry: number; } +interface CacheOptions { + ttl: number; // time in ms/ +} + const featureFlagCache = new Map(); const isExpired = (entry: CacheEntry): boolean => { return Date.now() > entry.expiry; }; -export const getFeatureFlag = async (prisma: PrismaClient, slug: keyof AppFlags): Promise => { +export const getFeatureFlag = async ( + prisma: PrismaClient, + slug: keyof AppFlags, + options?: CacheOptions = { ttl: 5 * 60 * 1000 } +): Promise => { const cacheEntry = featureFlagCache.get(slug); // Check if the flag is in the cache and not expired @@ -41,8 +49,7 @@ export const getFeatureFlag = async (prisma: PrismaClient, slug: keyof AppFlags) const isEnabled = Boolean(flag && flag.enabled); - // Calculate expiry time (current time + 5 minutes) - const expiry = Date.now() + 5 * 60 * 1000; // 5 minutes in milliseconds + const expiry = Date.now() + options.ttl; // Store the flag in the cache with its expiry time featureFlagCache.set(slug, { value: isEnabled, expiry }); diff --git a/packages/kysely/types.ts b/packages/kysely/types.ts new file mode 100644 index 00000000000000..7fa002af77a5e8 --- /dev/null +++ b/packages/kysely/types.ts @@ -0,0 +1,866 @@ +import type { ColumnType } from "kysely"; + +export type Generated = T extends ColumnType + ? ColumnType + : ColumnType; +export type Timestamp = ColumnType; + +export const SchedulingType = { + ROUND_ROBIN: "roundRobin", + COLLECTIVE: "collective", + MANAGED: "managed", +} as const; +export type SchedulingType = (typeof SchedulingType)[keyof typeof SchedulingType]; +export const PeriodType = { + UNLIMITED: "unlimited", + ROLLING: "rolling", + RANGE: "range", +} as const; +export type PeriodType = (typeof PeriodType)[keyof typeof PeriodType]; +export const IdentityProvider = { + CAL: "CAL", + GOOGLE: "GOOGLE", + SAML: "SAML", +} as const; +export type IdentityProvider = (typeof IdentityProvider)[keyof typeof IdentityProvider]; +export const UserPermissionRole = { + USER: "USER", + ADMIN: "ADMIN", +} as const; +export type UserPermissionRole = (typeof UserPermissionRole)[keyof typeof UserPermissionRole]; +export const MembershipRole = { + MEMBER: "MEMBER", + ADMIN: "ADMIN", + OWNER: "OWNER", +} as const; +export type MembershipRole = (typeof MembershipRole)[keyof typeof MembershipRole]; +export const BookingStatus = { + CANCELLED: "cancelled", + ACCEPTED: "accepted", + REJECTED: "rejected", + PENDING: "pending", + AWAITING_HOST: "awaiting_host", +} as const; +export type BookingStatus = (typeof BookingStatus)[keyof typeof BookingStatus]; +export const EventTypeCustomInputType = { + TEXT: "text", + TEXTLONG: "textLong", + NUMBER: "number", + BOOL: "bool", + RADIO: "radio", + PHONE: "phone", +} as const; +export type EventTypeCustomInputType = + (typeof EventTypeCustomInputType)[keyof typeof EventTypeCustomInputType]; +export const ReminderType = { + PENDING_BOOKING_CONFIRMATION: "PENDING_BOOKING_CONFIRMATION", +} as const; +export type ReminderType = (typeof ReminderType)[keyof typeof ReminderType]; +export const PaymentOption = { + ON_BOOKING: "ON_BOOKING", + HOLD: "HOLD", +} as const; +export type PaymentOption = (typeof PaymentOption)[keyof typeof PaymentOption]; +export const WebhookTriggerEvents = { + BOOKING_CREATED: "BOOKING_CREATED", + BOOKING_PAYMENT_INITIATED: "BOOKING_PAYMENT_INITIATED", + BOOKING_PAID: "BOOKING_PAID", + BOOKING_RESCHEDULED: "BOOKING_RESCHEDULED", + BOOKING_REQUESTED: "BOOKING_REQUESTED", + BOOKING_CANCELLED: "BOOKING_CANCELLED", + BOOKING_REJECTED: "BOOKING_REJECTED", + FORM_SUBMITTED: "FORM_SUBMITTED", + MEETING_ENDED: "MEETING_ENDED", + MEETING_STARTED: "MEETING_STARTED", + RECORDING_READY: "RECORDING_READY", + INSTANT_MEETING: "INSTANT_MEETING", +} as const; +export type WebhookTriggerEvents = (typeof WebhookTriggerEvents)[keyof typeof WebhookTriggerEvents]; +export const AppCategories = { + calendar: "calendar", + messaging: "messaging", + other: "other", + payment: "payment", + video: "video", + web3: "web3", + automation: "automation", + analytics: "analytics", + conferencing: "conferencing", + crm: "crm", +} as const; +export type AppCategories = (typeof AppCategories)[keyof typeof AppCategories]; +export const WorkflowTriggerEvents = { + BEFORE_EVENT: "BEFORE_EVENT", + EVENT_CANCELLED: "EVENT_CANCELLED", + NEW_EVENT: "NEW_EVENT", + AFTER_EVENT: "AFTER_EVENT", + RESCHEDULE_EVENT: "RESCHEDULE_EVENT", +} as const; +export type WorkflowTriggerEvents = (typeof WorkflowTriggerEvents)[keyof typeof WorkflowTriggerEvents]; +export const WorkflowActions = { + EMAIL_HOST: "EMAIL_HOST", + EMAIL_ATTENDEE: "EMAIL_ATTENDEE", + SMS_ATTENDEE: "SMS_ATTENDEE", + SMS_NUMBER: "SMS_NUMBER", + EMAIL_ADDRESS: "EMAIL_ADDRESS", + WHATSAPP_ATTENDEE: "WHATSAPP_ATTENDEE", + WHATSAPP_NUMBER: "WHATSAPP_NUMBER", +} as const; +export type WorkflowActions = (typeof WorkflowActions)[keyof typeof WorkflowActions]; +export const TimeUnit = { + DAY: "day", + HOUR: "hour", + MINUTE: "minute", +} as const; +export type TimeUnit = (typeof TimeUnit)[keyof typeof TimeUnit]; +export const WorkflowTemplates = { + REMINDER: "REMINDER", + CUSTOM: "CUSTOM", + CANCELLED: "CANCELLED", + RESCHEDULED: "RESCHEDULED", + COMPLETED: "COMPLETED", +} as const; +export type WorkflowTemplates = (typeof WorkflowTemplates)[keyof typeof WorkflowTemplates]; +export const WorkflowMethods = { + EMAIL: "EMAIL", + SMS: "SMS", + WHATSAPP: "WHATSAPP", +} as const; +export type WorkflowMethods = (typeof WorkflowMethods)[keyof typeof WorkflowMethods]; +export const FeatureType = { + RELEASE: "RELEASE", + EXPERIMENT: "EXPERIMENT", + OPERATIONAL: "OPERATIONAL", + KILL_SWITCH: "KILL_SWITCH", + PERMISSION: "PERMISSION", +} as const; +export type FeatureType = (typeof FeatureType)[keyof typeof FeatureType]; +export const AccessScope = { + READ_BOOKING: "READ_BOOKING", + READ_PROFILE: "READ_PROFILE", +} as const; +export type AccessScope = (typeof AccessScope)[keyof typeof AccessScope]; +export const RedirectType = { + UserEventType: "user-event-type", + TeamEventType: "team-event-type", + User: "user", + Team: "team", +} as const; +export type RedirectType = (typeof RedirectType)[keyof typeof RedirectType]; +export type AccessCode = { + id: Generated; + code: string; + clientId: string | null; + expiresAt: Timestamp; + scopes: AccessScope[]; + userId: number | null; + teamId: number | null; +}; +export type AccessToken = { + id: Generated; + secret: string; + created_at: Generated; + expires_at: Timestamp; + platform_oauth_client_id: string; + user_id: number; +}; +export type Account = { + id: string; + userId: number; + type: string; + provider: string; + providerAccountId: string; + refresh_token: string | null; + access_token: string | null; + expires_at: number | null; + token_type: string | null; + scope: string | null; + id_token: string | null; + session_state: string | null; +}; +export type ApiKey = { + id: string; + userId: number; + teamId: number | null; + note: string | null; + createdAt: Generated; + expiresAt: Timestamp | null; + lastUsedAt: Timestamp | null; + hashedKey: string; + appId: string | null; +}; +export type App = { + slug: string; + dirName: string; + keys: unknown | null; + categories: AppCategories[]; + createdAt: Generated; + updatedAt: Timestamp; + enabled: Generated; +}; +export type App_RoutingForms_Form = { + id: string; + description: string | null; + position: Generated; + routes: unknown | null; + createdAt: Generated; + updatedAt: Timestamp; + name: string; + fields: unknown | null; + userId: number; + teamId: number | null; + disabled: Generated; + /** + * @zod.custom(imports.RoutingFormSettings) + */ + settings: unknown | null; +}; +export type App_RoutingForms_FormResponse = { + id: Generated; + formFillerId: string; + formId: string; + response: unknown; + createdAt: Generated; +}; +export type Attendee = { + id: Generated; + email: string; + name: string; + timeZone: string; + locale: Generated; + bookingId: number | null; +}; +export type Availability = { + id: Generated; + userId: number | null; + eventTypeId: number | null; + days: number[]; + startTime: Timestamp; + endTime: Timestamp; + date: Timestamp | null; + scheduleId: number | null; +}; +export type Avatar = { + teamId: Generated; + userId: Generated; + data: string; + objectKey: string; +}; +export type Booking = { + id: Generated; + uid: string; + userId: number | null; + eventTypeId: number | null; + title: string; + description: string | null; + customInputs: unknown | null; + /** + * @zod.custom(imports.bookingResponses) + */ + responses: unknown | null; + startTime: Timestamp; + endTime: Timestamp; + location: string | null; + createdAt: Generated; + updatedAt: Timestamp | null; + status: Generated; + paid: Generated; + destinationCalendarId: number | null; + cancellationReason: string | null; + rejectionReason: string | null; + dynamicEventSlugRef: string | null; + dynamicGroupSlugRef: string | null; + rescheduled: boolean | null; + fromReschedule: string | null; + recurringEventId: string | null; + smsReminderNumber: string | null; + scheduledJobs: string[]; + /** + * @zod.custom(imports.bookingMetadataSchema) + */ + metadata: unknown | null; + isRecorded: Generated; + iCalUID: Generated; + iCalSequence: Generated; +}; +export type BookingReference = { + id: Generated; + /** + * @zod.min(1) + */ + type: string; + /** + * @zod.min(1) + */ + uid: string; + meetingId: string | null; + thirdPartyRecurringEventId: string | null; + meetingPassword: string | null; + meetingUrl: string | null; + bookingId: number | null; + externalCalendarId: string | null; + deleted: boolean | null; + credentialId: number | null; +}; +export type BookingSeat = { + id: Generated; + referenceUid: string; + bookingId: number; + attendeeId: number; + /** + * @zod.custom(imports.bookingSeatDataSchema) + */ + data: unknown | null; +}; +export type BookingTimeStatus = { + id: number; + uid: string | null; + eventTypeId: number | null; + title: string | null; + description: string | null; + startTime: Timestamp | null; + endTime: Timestamp | null; + createdAt: Timestamp | null; + location: string | null; + paid: boolean | null; + status: BookingStatus | null; + rescheduled: boolean | null; + userId: number | null; + teamId: number | null; + eventLength: number | null; + timeStatus: string | null; + eventParentId: number | null; + userEmail: string | null; + username: string | null; +}; +export type CalendarCache = { + key: string; + value: unknown; + expiresAt: Timestamp; + credentialId: number; +}; +export type Credential = { + id: Generated; + type: string; + key: unknown; + userId: number | null; + teamId: number | null; + appId: string | null; + subscriptionId: string | null; + paymentStatus: string | null; + billingCycleStart: number | null; + invalid: Generated; +}; +export type Deployment = { + /** + * This is a single row table, so we use a fixed id + */ + id: Generated; + logo: string | null; + /** + * @zod.custom(imports.DeploymentTheme) + */ + theme: unknown | null; + licenseKey: string | null; + agreedLicenseAt: Timestamp | null; +}; +export type DestinationCalendar = { + id: Generated; + integration: string; + externalId: string; + userId: number | null; + eventTypeId: number | null; + credentialId: number | null; +}; +export type EventType = { + id: Generated; + /** + * @zod.min(1) + */ + title: string; + /** + * @zod.custom(imports.eventTypeSlug) + */ + slug: string; + description: string | null; + position: Generated; + /** + * @zod.custom(imports.eventTypeLocations) + */ + locations: unknown | null; + /** + * @zod.min(1) + */ + length: number; + offsetStart: Generated; + hidden: Generated; + userId: number | null; + profileId: number | null; + teamId: number | null; + eventName: string | null; + parentId: number | null; + /** + * @zod.custom(imports.eventTypeBookingFields) + */ + bookingFields: unknown | null; + timeZone: string | null; + periodType: Generated; + /** + * @zod.custom(imports.coerceToDate) + */ + periodStartDate: Timestamp | null; + /** + * @zod.custom(imports.coerceToDate) + */ + periodEndDate: Timestamp | null; + periodDays: number | null; + periodCountCalendarDays: boolean | null; + lockTimeZoneToggleOnBookingPage: Generated; + requiresConfirmation: Generated; + requiresBookerEmailVerification: Generated; + /** + * @zod.custom(imports.recurringEventType) + */ + recurringEvent: unknown | null; + disableGuests: Generated; + hideCalendarNotes: Generated; + /** + * @zod.min(0) + */ + minimumBookingNotice: Generated; + beforeEventBuffer: Generated; + afterEventBuffer: Generated; + seatsPerTimeSlot: number | null; + onlyShowFirstAvailableSlot: Generated; + seatsShowAttendees: Generated; + seatsShowAvailabilityCount: Generated; + schedulingType: SchedulingType | null; + scheduleId: number | null; + price: Generated; + currency: Generated; + slotInterval: number | null; + /** + * @zod.custom(imports.EventTypeMetaDataSchema) + */ + metadata: unknown | null; + /** + * @zod.custom(imports.successRedirectUrl) + */ + successRedirectUrl: string | null; + /** + * @zod.custom(imports.intervalLimitsType) + */ + bookingLimits: unknown | null; + /** + * @zod.custom(imports.intervalLimitsType) + */ + durationLimits: unknown | null; + isInstantEvent: Generated; + assignAllTeamMembers: Generated; +}; +export type EventTypeCustomInput = { + id: Generated; + eventTypeId: number; + label: string; + type: EventTypeCustomInputType; + /** + * @zod.custom(imports.customInputOptionSchema) + */ + options: unknown | null; + required: boolean; + placeholder: Generated; +}; +export type Feature = { + slug: string; + enabled: Generated; + description: string | null; + type: Generated; + stale: Generated; + lastUsedAt: Timestamp | null; + createdAt: Generated; + updatedAt: Generated; + updatedBy: number | null; +}; +export type Feedback = { + id: Generated; + date: Generated; + userId: number; + rating: string; + comment: string | null; +}; +export type HashedLink = { + id: Generated; + link: string; + eventTypeId: number; +}; +export type Host = { + userId: number; + eventTypeId: number; + isFixed: Generated; +}; +export type Impersonations = { + id: Generated; + createdAt: Generated; + impersonatedUserId: number; + impersonatedById: number; +}; +export type InstantMeetingToken = { + id: Generated; + token: string; + expires: Timestamp; + teamId: number; + bookingId: number | null; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type Membership = { + id: Generated; + teamId: number; + userId: number; + accepted: Generated; + role: MembershipRole; + disableImpersonation: Generated; +}; +export type OAuthClient = { + clientId: string; + redirectUri: string; + clientSecret: string; + name: string; + logo: string | null; +}; +export type OutOfOfficeEntry = { + id: Generated; + uuid: string; + start: Timestamp; + end: Timestamp; + userId: number; + toUserId: number | null; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type Payment = { + id: Generated; + uid: string; + appId: string | null; + bookingId: number; + amount: number; + fee: number; + currency: string; + success: boolean; + refunded: boolean; + data: unknown; + externalId: string; + paymentOption: Generated; +}; +export type PlatformAuthorizationToken = { + id: string; + platform_oauth_client_id: string; + user_id: number; + created_at: Generated; +}; +export type PlatformOAuthClient = { + id: string; + name: string; + secret: string; + permissions: number; + logo: string | null; + redirect_uris: string[]; + organization_id: number; + created_at: Generated; +}; +export type PlatformOAuthClientToUser = { + A: string; + B: number; +}; +export type Profile = { + id: Generated; + uid: string; + userId: number; + organizationId: number; + username: string; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type RefreshToken = { + id: Generated; + secret: string; + created_at: Generated; + expires_at: Timestamp; + platform_oauth_client_id: string; + user_id: number; +}; +export type ReminderMail = { + id: Generated; + referenceId: number; + reminderType: ReminderType; + elapsedMinutes: number; + createdAt: Generated; +}; +export type ResetPasswordRequest = { + id: string; + createdAt: Generated; + updatedAt: Timestamp; + email: string; + expires: Timestamp; +}; +export type Schedule = { + id: Generated; + userId: number; + name: string; + timeZone: string | null; +}; +export type SelectedCalendar = { + userId: number; + integration: string; + externalId: string; + credentialId: number | null; +}; +export type SelectedSlots = { + id: Generated; + eventTypeId: number; + userId: number; + slotUtcStartDate: Timestamp; + slotUtcEndDate: Timestamp; + uid: string; + releaseAt: Timestamp; + isSeat: Generated; +}; +export type Session = { + id: string; + sessionToken: string; + userId: number; + expires: Timestamp; +}; +export type Team = { + id: Generated; + /** + * @zod.min(1) + */ + name: string; + /** + * @zod.min(1) + */ + slug: string | null; + logo: string | null; + logoUrl: string | null; + calVideoLogo: string | null; + appLogo: string | null; + appIconLogo: string | null; + bio: string | null; + hideBranding: Generated; + isPrivate: Generated; + hideBookATeamMember: Generated; + createdAt: Generated; + /** + * @zod.custom(imports.teamMetadataSchema) + */ + metadata: unknown | null; + theme: string | null; + brandColor: string | null; + darkBrandColor: string | null; + parentId: number | null; + timeFormat: number | null; + timeZone: Generated; + weekStart: Generated; + pendingPayment: Generated; +}; +export type TempOrgRedirect = { + id: Generated; + from: string; + fromOrgId: number; + type: RedirectType; + toUrl: string; + enabled: Generated; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type User = { + id: Generated; + username: string | null; + name: string | null; + /** + * @zod.email() + */ + email: string; + emailVerified: Timestamp | null; + password: string | null; + bio: string | null; + avatar: string | null; + avatarUrl: string | null; + timeZone: Generated; + weekStart: Generated; + startTime: Generated; + endTime: Generated; + bufferTime: Generated; + hideBranding: Generated; + theme: string | null; + created: Generated; + trialEndsAt: Timestamp | null; + defaultScheduleId: number | null; + completedOnboarding: Generated; + locale: string | null; + timeFormat: Generated; + twoFactorSecret: string | null; + twoFactorEnabled: Generated; + backupCodes: string | null; + identityProvider: Generated; + identityProviderId: string | null; + invitedTo: number | null; + brandColor: string | null; + darkBrandColor: string | null; + away: Generated; + allowDynamicBooking: Generated; + allowSEOIndexing: Generated; + receiveMonthlyDigestEmail: Generated; + /** + * @zod.custom(imports.userMetadata) + */ + metadata: unknown | null; + verified: Generated; + role: Generated; + disableImpersonation: Generated; + organizationId: number | null; + locked: Generated; + movedToProfileId: number | null; +}; +export type user_eventtype = { + A: number; + B: number; +}; +export type VerificationToken = { + id: Generated; + identifier: string; + token: string; + expires: Timestamp; + expiresInDays: number | null; + createdAt: Generated; + updatedAt: Timestamp; + teamId: number | null; +}; +export type VerifiedNumber = { + id: Generated; + userId: number | null; + teamId: number | null; + phoneNumber: string; +}; +export type Webhook = { + id: string; + userId: number | null; + teamId: number | null; + eventTypeId: number | null; + /** + * @zod.url() + */ + subscriberUrl: string; + payloadTemplate: string | null; + createdAt: Generated; + active: Generated; + eventTriggers: WebhookTriggerEvents[]; + appId: string | null; + secret: string | null; +}; +export type WebhookScheduledTriggers = { + id: Generated; + jobName: string; + subscriberUrl: string; + payload: string; + startAfter: Timestamp; + retryCount: Generated; + createdAt: Generated; +}; +export type Workflow = { + id: Generated; + position: Generated; + name: string; + userId: number | null; + teamId: number | null; + trigger: WorkflowTriggerEvents; + time: number | null; + timeUnit: TimeUnit | null; +}; +export type WorkflowReminder = { + id: Generated; + bookingUid: string | null; + method: WorkflowMethods; + scheduledDate: Timestamp; + referenceId: string | null; + scheduled: boolean; + workflowStepId: number | null; + cancelled: boolean | null; + seatReferenceId: string | null; + isMandatoryReminder: Generated; +}; +export type WorkflowsOnEventTypes = { + id: Generated; + workflowId: number; + eventTypeId: number; +}; +export type WorkflowStep = { + id: Generated; + stepNumber: number; + action: WorkflowActions; + workflowId: number; + sendTo: string | null; + reminderBody: string | null; + emailSubject: string | null; + template: Generated; + numberRequired: boolean | null; + sender: string | null; + numberVerificationPending: Generated; + includeCalendarEvent: Generated; +}; +export type DB = { + _PlatformOAuthClientToUser: PlatformOAuthClientToUser; + _user_eventtype: user_eventtype; + AccessCode: AccessCode; + Account: Account; + ApiKey: ApiKey; + App: App; + App_RoutingForms_Form: App_RoutingForms_Form; + App_RoutingForms_FormResponse: App_RoutingForms_FormResponse; + Attendee: Attendee; + Availability: Availability; + avatars: Avatar; + Booking: Booking; + BookingReference: BookingReference; + BookingSeat: BookingSeat; + BookingTimeStatus: BookingTimeStatus; + CalendarCache: CalendarCache; + Credential: Credential; + Deployment: Deployment; + DestinationCalendar: DestinationCalendar; + EventType: EventType; + EventTypeCustomInput: EventTypeCustomInput; + Feature: Feature; + Feedback: Feedback; + HashedLink: HashedLink; + Host: Host; + Impersonations: Impersonations; + InstantMeetingToken: InstantMeetingToken; + Membership: Membership; + OAuthClient: OAuthClient; + OutOfOfficeEntry: OutOfOfficeEntry; + Payment: Payment; + platform_access_tokens: AccessToken; + platform_authorization_token: PlatformAuthorizationToken; + platform_oauth_clients: PlatformOAuthClient; + platform_refresh_token: RefreshToken; + Profile: Profile; + ReminderMail: ReminderMail; + ResetPasswordRequest: ResetPasswordRequest; + Schedule: Schedule; + SelectedCalendar: SelectedCalendar; + SelectedSlots: SelectedSlots; + Session: Session; + Team: Team; + TempOrgRedirect: TempOrgRedirect; + users: User; + VerificationToken: VerificationToken; + VerifiedNumber: VerifiedNumber; + Webhook: Webhook; + WebhookScheduledTriggers: WebhookScheduledTriggers; + Workflow: Workflow; + WorkflowReminder: WorkflowReminder; + WorkflowsOnEventTypes: WorkflowsOnEventTypes; + WorkflowStep: WorkflowStep; +}; From d8a84dae8ad81e01f88e36a4c6b0b2dfe9322b87 Mon Sep 17 00:00:00 2001 From: exception Date: Fri, 16 Feb 2024 18:05:01 -0300 Subject: [PATCH 05/13] chore: remove --- .../controllers/slots.controller.e2e-spec.ts | 28 - packages/kysely/types.ts | 866 ------------------ 2 files changed, 894 deletions(-) delete mode 100644 apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts delete mode 100644 packages/kysely/types.ts diff --git a/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts b/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts deleted file mode 100644 index d1022bcf313194..00000000000000 --- a/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { bootstrap } from "@/app"; -import { AppModule } from "@/app.module"; -import { HttpExceptionFilter } from "@/filters/http-exception.filter"; -import { PrismaExceptionFilter } from "@/filters/prisma-exception.filter"; -import { SlotsModule } from "@/modules/slots/slots.module"; -import type { INestApplication } from "@nestjs/common"; -import type { NestExpressApplication } from "@nestjs/platform-express"; -import { Test } from "@nestjs/testing"; - -describe("Platform Slots e2e", () => { - let app: INestApplication; - - beforeAll(async () => { - const moduleRef = await Test.createTestingModule({ - providers: [PrismaExceptionFilter, HttpExceptionFilter], - imports: [AppModule, SlotsModule], - }).compile(); - - app = moduleRef.createNestApplication(); - bootstrap(app as NestExpressApplication); - - await app.init(); - }); - - it("should be defined", () => { - expect(app).toBeDefined(); - }); -}); diff --git a/packages/kysely/types.ts b/packages/kysely/types.ts deleted file mode 100644 index 7fa002af77a5e8..00000000000000 --- a/packages/kysely/types.ts +++ /dev/null @@ -1,866 +0,0 @@ -import type { ColumnType } from "kysely"; - -export type Generated = T extends ColumnType - ? ColumnType - : ColumnType; -export type Timestamp = ColumnType; - -export const SchedulingType = { - ROUND_ROBIN: "roundRobin", - COLLECTIVE: "collective", - MANAGED: "managed", -} as const; -export type SchedulingType = (typeof SchedulingType)[keyof typeof SchedulingType]; -export const PeriodType = { - UNLIMITED: "unlimited", - ROLLING: "rolling", - RANGE: "range", -} as const; -export type PeriodType = (typeof PeriodType)[keyof typeof PeriodType]; -export const IdentityProvider = { - CAL: "CAL", - GOOGLE: "GOOGLE", - SAML: "SAML", -} as const; -export type IdentityProvider = (typeof IdentityProvider)[keyof typeof IdentityProvider]; -export const UserPermissionRole = { - USER: "USER", - ADMIN: "ADMIN", -} as const; -export type UserPermissionRole = (typeof UserPermissionRole)[keyof typeof UserPermissionRole]; -export const MembershipRole = { - MEMBER: "MEMBER", - ADMIN: "ADMIN", - OWNER: "OWNER", -} as const; -export type MembershipRole = (typeof MembershipRole)[keyof typeof MembershipRole]; -export const BookingStatus = { - CANCELLED: "cancelled", - ACCEPTED: "accepted", - REJECTED: "rejected", - PENDING: "pending", - AWAITING_HOST: "awaiting_host", -} as const; -export type BookingStatus = (typeof BookingStatus)[keyof typeof BookingStatus]; -export const EventTypeCustomInputType = { - TEXT: "text", - TEXTLONG: "textLong", - NUMBER: "number", - BOOL: "bool", - RADIO: "radio", - PHONE: "phone", -} as const; -export type EventTypeCustomInputType = - (typeof EventTypeCustomInputType)[keyof typeof EventTypeCustomInputType]; -export const ReminderType = { - PENDING_BOOKING_CONFIRMATION: "PENDING_BOOKING_CONFIRMATION", -} as const; -export type ReminderType = (typeof ReminderType)[keyof typeof ReminderType]; -export const PaymentOption = { - ON_BOOKING: "ON_BOOKING", - HOLD: "HOLD", -} as const; -export type PaymentOption = (typeof PaymentOption)[keyof typeof PaymentOption]; -export const WebhookTriggerEvents = { - BOOKING_CREATED: "BOOKING_CREATED", - BOOKING_PAYMENT_INITIATED: "BOOKING_PAYMENT_INITIATED", - BOOKING_PAID: "BOOKING_PAID", - BOOKING_RESCHEDULED: "BOOKING_RESCHEDULED", - BOOKING_REQUESTED: "BOOKING_REQUESTED", - BOOKING_CANCELLED: "BOOKING_CANCELLED", - BOOKING_REJECTED: "BOOKING_REJECTED", - FORM_SUBMITTED: "FORM_SUBMITTED", - MEETING_ENDED: "MEETING_ENDED", - MEETING_STARTED: "MEETING_STARTED", - RECORDING_READY: "RECORDING_READY", - INSTANT_MEETING: "INSTANT_MEETING", -} as const; -export type WebhookTriggerEvents = (typeof WebhookTriggerEvents)[keyof typeof WebhookTriggerEvents]; -export const AppCategories = { - calendar: "calendar", - messaging: "messaging", - other: "other", - payment: "payment", - video: "video", - web3: "web3", - automation: "automation", - analytics: "analytics", - conferencing: "conferencing", - crm: "crm", -} as const; -export type AppCategories = (typeof AppCategories)[keyof typeof AppCategories]; -export const WorkflowTriggerEvents = { - BEFORE_EVENT: "BEFORE_EVENT", - EVENT_CANCELLED: "EVENT_CANCELLED", - NEW_EVENT: "NEW_EVENT", - AFTER_EVENT: "AFTER_EVENT", - RESCHEDULE_EVENT: "RESCHEDULE_EVENT", -} as const; -export type WorkflowTriggerEvents = (typeof WorkflowTriggerEvents)[keyof typeof WorkflowTriggerEvents]; -export const WorkflowActions = { - EMAIL_HOST: "EMAIL_HOST", - EMAIL_ATTENDEE: "EMAIL_ATTENDEE", - SMS_ATTENDEE: "SMS_ATTENDEE", - SMS_NUMBER: "SMS_NUMBER", - EMAIL_ADDRESS: "EMAIL_ADDRESS", - WHATSAPP_ATTENDEE: "WHATSAPP_ATTENDEE", - WHATSAPP_NUMBER: "WHATSAPP_NUMBER", -} as const; -export type WorkflowActions = (typeof WorkflowActions)[keyof typeof WorkflowActions]; -export const TimeUnit = { - DAY: "day", - HOUR: "hour", - MINUTE: "minute", -} as const; -export type TimeUnit = (typeof TimeUnit)[keyof typeof TimeUnit]; -export const WorkflowTemplates = { - REMINDER: "REMINDER", - CUSTOM: "CUSTOM", - CANCELLED: "CANCELLED", - RESCHEDULED: "RESCHEDULED", - COMPLETED: "COMPLETED", -} as const; -export type WorkflowTemplates = (typeof WorkflowTemplates)[keyof typeof WorkflowTemplates]; -export const WorkflowMethods = { - EMAIL: "EMAIL", - SMS: "SMS", - WHATSAPP: "WHATSAPP", -} as const; -export type WorkflowMethods = (typeof WorkflowMethods)[keyof typeof WorkflowMethods]; -export const FeatureType = { - RELEASE: "RELEASE", - EXPERIMENT: "EXPERIMENT", - OPERATIONAL: "OPERATIONAL", - KILL_SWITCH: "KILL_SWITCH", - PERMISSION: "PERMISSION", -} as const; -export type FeatureType = (typeof FeatureType)[keyof typeof FeatureType]; -export const AccessScope = { - READ_BOOKING: "READ_BOOKING", - READ_PROFILE: "READ_PROFILE", -} as const; -export type AccessScope = (typeof AccessScope)[keyof typeof AccessScope]; -export const RedirectType = { - UserEventType: "user-event-type", - TeamEventType: "team-event-type", - User: "user", - Team: "team", -} as const; -export type RedirectType = (typeof RedirectType)[keyof typeof RedirectType]; -export type AccessCode = { - id: Generated; - code: string; - clientId: string | null; - expiresAt: Timestamp; - scopes: AccessScope[]; - userId: number | null; - teamId: number | null; -}; -export type AccessToken = { - id: Generated; - secret: string; - created_at: Generated; - expires_at: Timestamp; - platform_oauth_client_id: string; - user_id: number; -}; -export type Account = { - id: string; - userId: number; - type: string; - provider: string; - providerAccountId: string; - refresh_token: string | null; - access_token: string | null; - expires_at: number | null; - token_type: string | null; - scope: string | null; - id_token: string | null; - session_state: string | null; -}; -export type ApiKey = { - id: string; - userId: number; - teamId: number | null; - note: string | null; - createdAt: Generated; - expiresAt: Timestamp | null; - lastUsedAt: Timestamp | null; - hashedKey: string; - appId: string | null; -}; -export type App = { - slug: string; - dirName: string; - keys: unknown | null; - categories: AppCategories[]; - createdAt: Generated; - updatedAt: Timestamp; - enabled: Generated; -}; -export type App_RoutingForms_Form = { - id: string; - description: string | null; - position: Generated; - routes: unknown | null; - createdAt: Generated; - updatedAt: Timestamp; - name: string; - fields: unknown | null; - userId: number; - teamId: number | null; - disabled: Generated; - /** - * @zod.custom(imports.RoutingFormSettings) - */ - settings: unknown | null; -}; -export type App_RoutingForms_FormResponse = { - id: Generated; - formFillerId: string; - formId: string; - response: unknown; - createdAt: Generated; -}; -export type Attendee = { - id: Generated; - email: string; - name: string; - timeZone: string; - locale: Generated; - bookingId: number | null; -}; -export type Availability = { - id: Generated; - userId: number | null; - eventTypeId: number | null; - days: number[]; - startTime: Timestamp; - endTime: Timestamp; - date: Timestamp | null; - scheduleId: number | null; -}; -export type Avatar = { - teamId: Generated; - userId: Generated; - data: string; - objectKey: string; -}; -export type Booking = { - id: Generated; - uid: string; - userId: number | null; - eventTypeId: number | null; - title: string; - description: string | null; - customInputs: unknown | null; - /** - * @zod.custom(imports.bookingResponses) - */ - responses: unknown | null; - startTime: Timestamp; - endTime: Timestamp; - location: string | null; - createdAt: Generated; - updatedAt: Timestamp | null; - status: Generated; - paid: Generated; - destinationCalendarId: number | null; - cancellationReason: string | null; - rejectionReason: string | null; - dynamicEventSlugRef: string | null; - dynamicGroupSlugRef: string | null; - rescheduled: boolean | null; - fromReschedule: string | null; - recurringEventId: string | null; - smsReminderNumber: string | null; - scheduledJobs: string[]; - /** - * @zod.custom(imports.bookingMetadataSchema) - */ - metadata: unknown | null; - isRecorded: Generated; - iCalUID: Generated; - iCalSequence: Generated; -}; -export type BookingReference = { - id: Generated; - /** - * @zod.min(1) - */ - type: string; - /** - * @zod.min(1) - */ - uid: string; - meetingId: string | null; - thirdPartyRecurringEventId: string | null; - meetingPassword: string | null; - meetingUrl: string | null; - bookingId: number | null; - externalCalendarId: string | null; - deleted: boolean | null; - credentialId: number | null; -}; -export type BookingSeat = { - id: Generated; - referenceUid: string; - bookingId: number; - attendeeId: number; - /** - * @zod.custom(imports.bookingSeatDataSchema) - */ - data: unknown | null; -}; -export type BookingTimeStatus = { - id: number; - uid: string | null; - eventTypeId: number | null; - title: string | null; - description: string | null; - startTime: Timestamp | null; - endTime: Timestamp | null; - createdAt: Timestamp | null; - location: string | null; - paid: boolean | null; - status: BookingStatus | null; - rescheduled: boolean | null; - userId: number | null; - teamId: number | null; - eventLength: number | null; - timeStatus: string | null; - eventParentId: number | null; - userEmail: string | null; - username: string | null; -}; -export type CalendarCache = { - key: string; - value: unknown; - expiresAt: Timestamp; - credentialId: number; -}; -export type Credential = { - id: Generated; - type: string; - key: unknown; - userId: number | null; - teamId: number | null; - appId: string | null; - subscriptionId: string | null; - paymentStatus: string | null; - billingCycleStart: number | null; - invalid: Generated; -}; -export type Deployment = { - /** - * This is a single row table, so we use a fixed id - */ - id: Generated; - logo: string | null; - /** - * @zod.custom(imports.DeploymentTheme) - */ - theme: unknown | null; - licenseKey: string | null; - agreedLicenseAt: Timestamp | null; -}; -export type DestinationCalendar = { - id: Generated; - integration: string; - externalId: string; - userId: number | null; - eventTypeId: number | null; - credentialId: number | null; -}; -export type EventType = { - id: Generated; - /** - * @zod.min(1) - */ - title: string; - /** - * @zod.custom(imports.eventTypeSlug) - */ - slug: string; - description: string | null; - position: Generated; - /** - * @zod.custom(imports.eventTypeLocations) - */ - locations: unknown | null; - /** - * @zod.min(1) - */ - length: number; - offsetStart: Generated; - hidden: Generated; - userId: number | null; - profileId: number | null; - teamId: number | null; - eventName: string | null; - parentId: number | null; - /** - * @zod.custom(imports.eventTypeBookingFields) - */ - bookingFields: unknown | null; - timeZone: string | null; - periodType: Generated; - /** - * @zod.custom(imports.coerceToDate) - */ - periodStartDate: Timestamp | null; - /** - * @zod.custom(imports.coerceToDate) - */ - periodEndDate: Timestamp | null; - periodDays: number | null; - periodCountCalendarDays: boolean | null; - lockTimeZoneToggleOnBookingPage: Generated; - requiresConfirmation: Generated; - requiresBookerEmailVerification: Generated; - /** - * @zod.custom(imports.recurringEventType) - */ - recurringEvent: unknown | null; - disableGuests: Generated; - hideCalendarNotes: Generated; - /** - * @zod.min(0) - */ - minimumBookingNotice: Generated; - beforeEventBuffer: Generated; - afterEventBuffer: Generated; - seatsPerTimeSlot: number | null; - onlyShowFirstAvailableSlot: Generated; - seatsShowAttendees: Generated; - seatsShowAvailabilityCount: Generated; - schedulingType: SchedulingType | null; - scheduleId: number | null; - price: Generated; - currency: Generated; - slotInterval: number | null; - /** - * @zod.custom(imports.EventTypeMetaDataSchema) - */ - metadata: unknown | null; - /** - * @zod.custom(imports.successRedirectUrl) - */ - successRedirectUrl: string | null; - /** - * @zod.custom(imports.intervalLimitsType) - */ - bookingLimits: unknown | null; - /** - * @zod.custom(imports.intervalLimitsType) - */ - durationLimits: unknown | null; - isInstantEvent: Generated; - assignAllTeamMembers: Generated; -}; -export type EventTypeCustomInput = { - id: Generated; - eventTypeId: number; - label: string; - type: EventTypeCustomInputType; - /** - * @zod.custom(imports.customInputOptionSchema) - */ - options: unknown | null; - required: boolean; - placeholder: Generated; -}; -export type Feature = { - slug: string; - enabled: Generated; - description: string | null; - type: Generated; - stale: Generated; - lastUsedAt: Timestamp | null; - createdAt: Generated; - updatedAt: Generated; - updatedBy: number | null; -}; -export type Feedback = { - id: Generated; - date: Generated; - userId: number; - rating: string; - comment: string | null; -}; -export type HashedLink = { - id: Generated; - link: string; - eventTypeId: number; -}; -export type Host = { - userId: number; - eventTypeId: number; - isFixed: Generated; -}; -export type Impersonations = { - id: Generated; - createdAt: Generated; - impersonatedUserId: number; - impersonatedById: number; -}; -export type InstantMeetingToken = { - id: Generated; - token: string; - expires: Timestamp; - teamId: number; - bookingId: number | null; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type Membership = { - id: Generated; - teamId: number; - userId: number; - accepted: Generated; - role: MembershipRole; - disableImpersonation: Generated; -}; -export type OAuthClient = { - clientId: string; - redirectUri: string; - clientSecret: string; - name: string; - logo: string | null; -}; -export type OutOfOfficeEntry = { - id: Generated; - uuid: string; - start: Timestamp; - end: Timestamp; - userId: number; - toUserId: number | null; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type Payment = { - id: Generated; - uid: string; - appId: string | null; - bookingId: number; - amount: number; - fee: number; - currency: string; - success: boolean; - refunded: boolean; - data: unknown; - externalId: string; - paymentOption: Generated; -}; -export type PlatformAuthorizationToken = { - id: string; - platform_oauth_client_id: string; - user_id: number; - created_at: Generated; -}; -export type PlatformOAuthClient = { - id: string; - name: string; - secret: string; - permissions: number; - logo: string | null; - redirect_uris: string[]; - organization_id: number; - created_at: Generated; -}; -export type PlatformOAuthClientToUser = { - A: string; - B: number; -}; -export type Profile = { - id: Generated; - uid: string; - userId: number; - organizationId: number; - username: string; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type RefreshToken = { - id: Generated; - secret: string; - created_at: Generated; - expires_at: Timestamp; - platform_oauth_client_id: string; - user_id: number; -}; -export type ReminderMail = { - id: Generated; - referenceId: number; - reminderType: ReminderType; - elapsedMinutes: number; - createdAt: Generated; -}; -export type ResetPasswordRequest = { - id: string; - createdAt: Generated; - updatedAt: Timestamp; - email: string; - expires: Timestamp; -}; -export type Schedule = { - id: Generated; - userId: number; - name: string; - timeZone: string | null; -}; -export type SelectedCalendar = { - userId: number; - integration: string; - externalId: string; - credentialId: number | null; -}; -export type SelectedSlots = { - id: Generated; - eventTypeId: number; - userId: number; - slotUtcStartDate: Timestamp; - slotUtcEndDate: Timestamp; - uid: string; - releaseAt: Timestamp; - isSeat: Generated; -}; -export type Session = { - id: string; - sessionToken: string; - userId: number; - expires: Timestamp; -}; -export type Team = { - id: Generated; - /** - * @zod.min(1) - */ - name: string; - /** - * @zod.min(1) - */ - slug: string | null; - logo: string | null; - logoUrl: string | null; - calVideoLogo: string | null; - appLogo: string | null; - appIconLogo: string | null; - bio: string | null; - hideBranding: Generated; - isPrivate: Generated; - hideBookATeamMember: Generated; - createdAt: Generated; - /** - * @zod.custom(imports.teamMetadataSchema) - */ - metadata: unknown | null; - theme: string | null; - brandColor: string | null; - darkBrandColor: string | null; - parentId: number | null; - timeFormat: number | null; - timeZone: Generated; - weekStart: Generated; - pendingPayment: Generated; -}; -export type TempOrgRedirect = { - id: Generated; - from: string; - fromOrgId: number; - type: RedirectType; - toUrl: string; - enabled: Generated; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type User = { - id: Generated; - username: string | null; - name: string | null; - /** - * @zod.email() - */ - email: string; - emailVerified: Timestamp | null; - password: string | null; - bio: string | null; - avatar: string | null; - avatarUrl: string | null; - timeZone: Generated; - weekStart: Generated; - startTime: Generated; - endTime: Generated; - bufferTime: Generated; - hideBranding: Generated; - theme: string | null; - created: Generated; - trialEndsAt: Timestamp | null; - defaultScheduleId: number | null; - completedOnboarding: Generated; - locale: string | null; - timeFormat: Generated; - twoFactorSecret: string | null; - twoFactorEnabled: Generated; - backupCodes: string | null; - identityProvider: Generated; - identityProviderId: string | null; - invitedTo: number | null; - brandColor: string | null; - darkBrandColor: string | null; - away: Generated; - allowDynamicBooking: Generated; - allowSEOIndexing: Generated; - receiveMonthlyDigestEmail: Generated; - /** - * @zod.custom(imports.userMetadata) - */ - metadata: unknown | null; - verified: Generated; - role: Generated; - disableImpersonation: Generated; - organizationId: number | null; - locked: Generated; - movedToProfileId: number | null; -}; -export type user_eventtype = { - A: number; - B: number; -}; -export type VerificationToken = { - id: Generated; - identifier: string; - token: string; - expires: Timestamp; - expiresInDays: number | null; - createdAt: Generated; - updatedAt: Timestamp; - teamId: number | null; -}; -export type VerifiedNumber = { - id: Generated; - userId: number | null; - teamId: number | null; - phoneNumber: string; -}; -export type Webhook = { - id: string; - userId: number | null; - teamId: number | null; - eventTypeId: number | null; - /** - * @zod.url() - */ - subscriberUrl: string; - payloadTemplate: string | null; - createdAt: Generated; - active: Generated; - eventTriggers: WebhookTriggerEvents[]; - appId: string | null; - secret: string | null; -}; -export type WebhookScheduledTriggers = { - id: Generated; - jobName: string; - subscriberUrl: string; - payload: string; - startAfter: Timestamp; - retryCount: Generated; - createdAt: Generated; -}; -export type Workflow = { - id: Generated; - position: Generated; - name: string; - userId: number | null; - teamId: number | null; - trigger: WorkflowTriggerEvents; - time: number | null; - timeUnit: TimeUnit | null; -}; -export type WorkflowReminder = { - id: Generated; - bookingUid: string | null; - method: WorkflowMethods; - scheduledDate: Timestamp; - referenceId: string | null; - scheduled: boolean; - workflowStepId: number | null; - cancelled: boolean | null; - seatReferenceId: string | null; - isMandatoryReminder: Generated; -}; -export type WorkflowsOnEventTypes = { - id: Generated; - workflowId: number; - eventTypeId: number; -}; -export type WorkflowStep = { - id: Generated; - stepNumber: number; - action: WorkflowActions; - workflowId: number; - sendTo: string | null; - reminderBody: string | null; - emailSubject: string | null; - template: Generated; - numberRequired: boolean | null; - sender: string | null; - numberVerificationPending: Generated; - includeCalendarEvent: Generated; -}; -export type DB = { - _PlatformOAuthClientToUser: PlatformOAuthClientToUser; - _user_eventtype: user_eventtype; - AccessCode: AccessCode; - Account: Account; - ApiKey: ApiKey; - App: App; - App_RoutingForms_Form: App_RoutingForms_Form; - App_RoutingForms_FormResponse: App_RoutingForms_FormResponse; - Attendee: Attendee; - Availability: Availability; - avatars: Avatar; - Booking: Booking; - BookingReference: BookingReference; - BookingSeat: BookingSeat; - BookingTimeStatus: BookingTimeStatus; - CalendarCache: CalendarCache; - Credential: Credential; - Deployment: Deployment; - DestinationCalendar: DestinationCalendar; - EventType: EventType; - EventTypeCustomInput: EventTypeCustomInput; - Feature: Feature; - Feedback: Feedback; - HashedLink: HashedLink; - Host: Host; - Impersonations: Impersonations; - InstantMeetingToken: InstantMeetingToken; - Membership: Membership; - OAuthClient: OAuthClient; - OutOfOfficeEntry: OutOfOfficeEntry; - Payment: Payment; - platform_access_tokens: AccessToken; - platform_authorization_token: PlatformAuthorizationToken; - platform_oauth_clients: PlatformOAuthClient; - platform_refresh_token: RefreshToken; - Profile: Profile; - ReminderMail: ReminderMail; - ResetPasswordRequest: ResetPasswordRequest; - Schedule: Schedule; - SelectedCalendar: SelectedCalendar; - SelectedSlots: SelectedSlots; - Session: Session; - Team: Team; - TempOrgRedirect: TempOrgRedirect; - users: User; - VerificationToken: VerificationToken; - VerifiedNumber: VerifiedNumber; - Webhook: Webhook; - WebhookScheduledTriggers: WebhookScheduledTriggers; - Workflow: Workflow; - WorkflowReminder: WorkflowReminder; - WorkflowsOnEventTypes: WorkflowsOnEventTypes; - WorkflowStep: WorkflowStep; -}; From a823bc5c9fd037db03aade33fc39a670bc665613 Mon Sep 17 00:00:00 2001 From: exception Date: Fri, 16 Feb 2024 18:09:39 -0300 Subject: [PATCH 06/13] chore: fix tests --- packages/features/flags/server/utils.ts | 2 +- .../server/routers/loggedInViewer/updateProfile.handler.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/features/flags/server/utils.ts b/packages/features/flags/server/utils.ts index 25bc16eee1425b..3e8cac8cb014f6 100644 --- a/packages/features/flags/server/utils.ts +++ b/packages/features/flags/server/utils.ts @@ -31,7 +31,7 @@ const isExpired = (entry: CacheEntry): boolean => { export const getFeatureFlag = async ( prisma: PrismaClient, slug: keyof AppFlags, - options?: CacheOptions = { ttl: 5 * 60 * 1000 } + options: CacheOptions = { ttl: 5 * 60 * 1000 } ): Promise => { const cacheEntry = featureFlagCache.get(slug); diff --git a/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts b/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts index 75f262b34472ca..512bbe4096bd4c 100644 --- a/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts +++ b/packages/trpc/server/routers/loggedInViewer/updateProfile.handler.ts @@ -282,12 +282,12 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions) return { ...input, - email: sendEmailVerification && hasEmailChangedOnCalProvider ? user.email : input.email, + email: emailVerification && hasEmailChangedOnCalProvider ? user.email : input.email, signOutUser, passwordReset, avatarUrl: updatedUser.avatarUrl, hasEmailBeenChanged, - sendEmailVerification, + sendEmailVerification: emailVerification, }; }; From 9e4362be4fd8e48017ea0774e4196398aa2fff11 Mon Sep 17 00:00:00 2001 From: exception Date: Mon, 19 Feb 2024 10:51:33 -0300 Subject: [PATCH 07/13] chore: pre-fetch --- packages/features/flags/server/utils.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/features/flags/server/utils.ts b/packages/features/flags/server/utils.ts index 3e8cac8cb014f6..71b9fb8e0c848b 100644 --- a/packages/features/flags/server/utils.ts +++ b/packages/features/flags/server/utils.ts @@ -19,7 +19,7 @@ interface CacheEntry { } interface CacheOptions { - ttl: number; // time in ms/ + ttl: number; // time in ms } const featureFlagCache = new Map(); @@ -33,6 +33,18 @@ export const getFeatureFlag = async ( slug: keyof AppFlags, options: CacheOptions = { ttl: 5 * 60 * 1000 } ): Promise => { + // pre-compute all app flags, each one will independelty reload it's own state after expiry. + + if (featureFlagCache.size === 0) { + const flags = await prisma.feature.findMany({ orderBy: { slug: "asc" } }); + flags.forEach((flag) => { + featureFlagCache.set(flag.slug as keyof AppFlags, { + value: flag.enabled, + expiry: Date.now() + options.ttl, + }); + }); + } + const cacheEntry = featureFlagCache.get(slug); // Check if the flag is in the cache and not expired From dfe0389c964f749916ca8805bfc9449b2706bb76 Mon Sep 17 00:00:00 2001 From: exception Date: Mon, 19 Feb 2024 10:58:36 -0300 Subject: [PATCH 08/13] chore: nit --- .../controllers/slots.controller.e2e-spec.ts | 28 + packages/features/flags/server/utils.ts | 4 - packages/kysely/types.ts | 866 ++++++++++++++++++ 3 files changed, 894 insertions(+), 4 deletions(-) create mode 100644 apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts create mode 100644 packages/kysely/types.ts diff --git a/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts b/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts new file mode 100644 index 00000000000000..d1022bcf313194 --- /dev/null +++ b/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts @@ -0,0 +1,28 @@ +import { bootstrap } from "@/app"; +import { AppModule } from "@/app.module"; +import { HttpExceptionFilter } from "@/filters/http-exception.filter"; +import { PrismaExceptionFilter } from "@/filters/prisma-exception.filter"; +import { SlotsModule } from "@/modules/slots/slots.module"; +import type { INestApplication } from "@nestjs/common"; +import type { NestExpressApplication } from "@nestjs/platform-express"; +import { Test } from "@nestjs/testing"; + +describe("Platform Slots e2e", () => { + let app: INestApplication; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + providers: [PrismaExceptionFilter, HttpExceptionFilter], + imports: [AppModule, SlotsModule], + }).compile(); + + app = moduleRef.createNestApplication(); + bootstrap(app as NestExpressApplication); + + await app.init(); + }); + + it("should be defined", () => { + expect(app).toBeDefined(); + }); +}); diff --git a/packages/features/flags/server/utils.ts b/packages/features/flags/server/utils.ts index 71b9fb8e0c848b..001a8140871018 100644 --- a/packages/features/flags/server/utils.ts +++ b/packages/features/flags/server/utils.ts @@ -47,12 +47,10 @@ export const getFeatureFlag = async ( const cacheEntry = featureFlagCache.get(slug); - // Check if the flag is in the cache and not expired if (cacheEntry && !isExpired(cacheEntry)) { return cacheEntry.value; } - // Fetch from the database if not in cache or cache is expired const flag = await prisma.feature.findUnique({ where: { slug, @@ -60,10 +58,8 @@ export const getFeatureFlag = async ( }); const isEnabled = Boolean(flag && flag.enabled); - const expiry = Date.now() + options.ttl; - // Store the flag in the cache with its expiry time featureFlagCache.set(slug, { value: isEnabled, expiry }); return isEnabled; diff --git a/packages/kysely/types.ts b/packages/kysely/types.ts new file mode 100644 index 00000000000000..7fa002af77a5e8 --- /dev/null +++ b/packages/kysely/types.ts @@ -0,0 +1,866 @@ +import type { ColumnType } from "kysely"; + +export type Generated = T extends ColumnType + ? ColumnType + : ColumnType; +export type Timestamp = ColumnType; + +export const SchedulingType = { + ROUND_ROBIN: "roundRobin", + COLLECTIVE: "collective", + MANAGED: "managed", +} as const; +export type SchedulingType = (typeof SchedulingType)[keyof typeof SchedulingType]; +export const PeriodType = { + UNLIMITED: "unlimited", + ROLLING: "rolling", + RANGE: "range", +} as const; +export type PeriodType = (typeof PeriodType)[keyof typeof PeriodType]; +export const IdentityProvider = { + CAL: "CAL", + GOOGLE: "GOOGLE", + SAML: "SAML", +} as const; +export type IdentityProvider = (typeof IdentityProvider)[keyof typeof IdentityProvider]; +export const UserPermissionRole = { + USER: "USER", + ADMIN: "ADMIN", +} as const; +export type UserPermissionRole = (typeof UserPermissionRole)[keyof typeof UserPermissionRole]; +export const MembershipRole = { + MEMBER: "MEMBER", + ADMIN: "ADMIN", + OWNER: "OWNER", +} as const; +export type MembershipRole = (typeof MembershipRole)[keyof typeof MembershipRole]; +export const BookingStatus = { + CANCELLED: "cancelled", + ACCEPTED: "accepted", + REJECTED: "rejected", + PENDING: "pending", + AWAITING_HOST: "awaiting_host", +} as const; +export type BookingStatus = (typeof BookingStatus)[keyof typeof BookingStatus]; +export const EventTypeCustomInputType = { + TEXT: "text", + TEXTLONG: "textLong", + NUMBER: "number", + BOOL: "bool", + RADIO: "radio", + PHONE: "phone", +} as const; +export type EventTypeCustomInputType = + (typeof EventTypeCustomInputType)[keyof typeof EventTypeCustomInputType]; +export const ReminderType = { + PENDING_BOOKING_CONFIRMATION: "PENDING_BOOKING_CONFIRMATION", +} as const; +export type ReminderType = (typeof ReminderType)[keyof typeof ReminderType]; +export const PaymentOption = { + ON_BOOKING: "ON_BOOKING", + HOLD: "HOLD", +} as const; +export type PaymentOption = (typeof PaymentOption)[keyof typeof PaymentOption]; +export const WebhookTriggerEvents = { + BOOKING_CREATED: "BOOKING_CREATED", + BOOKING_PAYMENT_INITIATED: "BOOKING_PAYMENT_INITIATED", + BOOKING_PAID: "BOOKING_PAID", + BOOKING_RESCHEDULED: "BOOKING_RESCHEDULED", + BOOKING_REQUESTED: "BOOKING_REQUESTED", + BOOKING_CANCELLED: "BOOKING_CANCELLED", + BOOKING_REJECTED: "BOOKING_REJECTED", + FORM_SUBMITTED: "FORM_SUBMITTED", + MEETING_ENDED: "MEETING_ENDED", + MEETING_STARTED: "MEETING_STARTED", + RECORDING_READY: "RECORDING_READY", + INSTANT_MEETING: "INSTANT_MEETING", +} as const; +export type WebhookTriggerEvents = (typeof WebhookTriggerEvents)[keyof typeof WebhookTriggerEvents]; +export const AppCategories = { + calendar: "calendar", + messaging: "messaging", + other: "other", + payment: "payment", + video: "video", + web3: "web3", + automation: "automation", + analytics: "analytics", + conferencing: "conferencing", + crm: "crm", +} as const; +export type AppCategories = (typeof AppCategories)[keyof typeof AppCategories]; +export const WorkflowTriggerEvents = { + BEFORE_EVENT: "BEFORE_EVENT", + EVENT_CANCELLED: "EVENT_CANCELLED", + NEW_EVENT: "NEW_EVENT", + AFTER_EVENT: "AFTER_EVENT", + RESCHEDULE_EVENT: "RESCHEDULE_EVENT", +} as const; +export type WorkflowTriggerEvents = (typeof WorkflowTriggerEvents)[keyof typeof WorkflowTriggerEvents]; +export const WorkflowActions = { + EMAIL_HOST: "EMAIL_HOST", + EMAIL_ATTENDEE: "EMAIL_ATTENDEE", + SMS_ATTENDEE: "SMS_ATTENDEE", + SMS_NUMBER: "SMS_NUMBER", + EMAIL_ADDRESS: "EMAIL_ADDRESS", + WHATSAPP_ATTENDEE: "WHATSAPP_ATTENDEE", + WHATSAPP_NUMBER: "WHATSAPP_NUMBER", +} as const; +export type WorkflowActions = (typeof WorkflowActions)[keyof typeof WorkflowActions]; +export const TimeUnit = { + DAY: "day", + HOUR: "hour", + MINUTE: "minute", +} as const; +export type TimeUnit = (typeof TimeUnit)[keyof typeof TimeUnit]; +export const WorkflowTemplates = { + REMINDER: "REMINDER", + CUSTOM: "CUSTOM", + CANCELLED: "CANCELLED", + RESCHEDULED: "RESCHEDULED", + COMPLETED: "COMPLETED", +} as const; +export type WorkflowTemplates = (typeof WorkflowTemplates)[keyof typeof WorkflowTemplates]; +export const WorkflowMethods = { + EMAIL: "EMAIL", + SMS: "SMS", + WHATSAPP: "WHATSAPP", +} as const; +export type WorkflowMethods = (typeof WorkflowMethods)[keyof typeof WorkflowMethods]; +export const FeatureType = { + RELEASE: "RELEASE", + EXPERIMENT: "EXPERIMENT", + OPERATIONAL: "OPERATIONAL", + KILL_SWITCH: "KILL_SWITCH", + PERMISSION: "PERMISSION", +} as const; +export type FeatureType = (typeof FeatureType)[keyof typeof FeatureType]; +export const AccessScope = { + READ_BOOKING: "READ_BOOKING", + READ_PROFILE: "READ_PROFILE", +} as const; +export type AccessScope = (typeof AccessScope)[keyof typeof AccessScope]; +export const RedirectType = { + UserEventType: "user-event-type", + TeamEventType: "team-event-type", + User: "user", + Team: "team", +} as const; +export type RedirectType = (typeof RedirectType)[keyof typeof RedirectType]; +export type AccessCode = { + id: Generated; + code: string; + clientId: string | null; + expiresAt: Timestamp; + scopes: AccessScope[]; + userId: number | null; + teamId: number | null; +}; +export type AccessToken = { + id: Generated; + secret: string; + created_at: Generated; + expires_at: Timestamp; + platform_oauth_client_id: string; + user_id: number; +}; +export type Account = { + id: string; + userId: number; + type: string; + provider: string; + providerAccountId: string; + refresh_token: string | null; + access_token: string | null; + expires_at: number | null; + token_type: string | null; + scope: string | null; + id_token: string | null; + session_state: string | null; +}; +export type ApiKey = { + id: string; + userId: number; + teamId: number | null; + note: string | null; + createdAt: Generated; + expiresAt: Timestamp | null; + lastUsedAt: Timestamp | null; + hashedKey: string; + appId: string | null; +}; +export type App = { + slug: string; + dirName: string; + keys: unknown | null; + categories: AppCategories[]; + createdAt: Generated; + updatedAt: Timestamp; + enabled: Generated; +}; +export type App_RoutingForms_Form = { + id: string; + description: string | null; + position: Generated; + routes: unknown | null; + createdAt: Generated; + updatedAt: Timestamp; + name: string; + fields: unknown | null; + userId: number; + teamId: number | null; + disabled: Generated; + /** + * @zod.custom(imports.RoutingFormSettings) + */ + settings: unknown | null; +}; +export type App_RoutingForms_FormResponse = { + id: Generated; + formFillerId: string; + formId: string; + response: unknown; + createdAt: Generated; +}; +export type Attendee = { + id: Generated; + email: string; + name: string; + timeZone: string; + locale: Generated; + bookingId: number | null; +}; +export type Availability = { + id: Generated; + userId: number | null; + eventTypeId: number | null; + days: number[]; + startTime: Timestamp; + endTime: Timestamp; + date: Timestamp | null; + scheduleId: number | null; +}; +export type Avatar = { + teamId: Generated; + userId: Generated; + data: string; + objectKey: string; +}; +export type Booking = { + id: Generated; + uid: string; + userId: number | null; + eventTypeId: number | null; + title: string; + description: string | null; + customInputs: unknown | null; + /** + * @zod.custom(imports.bookingResponses) + */ + responses: unknown | null; + startTime: Timestamp; + endTime: Timestamp; + location: string | null; + createdAt: Generated; + updatedAt: Timestamp | null; + status: Generated; + paid: Generated; + destinationCalendarId: number | null; + cancellationReason: string | null; + rejectionReason: string | null; + dynamicEventSlugRef: string | null; + dynamicGroupSlugRef: string | null; + rescheduled: boolean | null; + fromReschedule: string | null; + recurringEventId: string | null; + smsReminderNumber: string | null; + scheduledJobs: string[]; + /** + * @zod.custom(imports.bookingMetadataSchema) + */ + metadata: unknown | null; + isRecorded: Generated; + iCalUID: Generated; + iCalSequence: Generated; +}; +export type BookingReference = { + id: Generated; + /** + * @zod.min(1) + */ + type: string; + /** + * @zod.min(1) + */ + uid: string; + meetingId: string | null; + thirdPartyRecurringEventId: string | null; + meetingPassword: string | null; + meetingUrl: string | null; + bookingId: number | null; + externalCalendarId: string | null; + deleted: boolean | null; + credentialId: number | null; +}; +export type BookingSeat = { + id: Generated; + referenceUid: string; + bookingId: number; + attendeeId: number; + /** + * @zod.custom(imports.bookingSeatDataSchema) + */ + data: unknown | null; +}; +export type BookingTimeStatus = { + id: number; + uid: string | null; + eventTypeId: number | null; + title: string | null; + description: string | null; + startTime: Timestamp | null; + endTime: Timestamp | null; + createdAt: Timestamp | null; + location: string | null; + paid: boolean | null; + status: BookingStatus | null; + rescheduled: boolean | null; + userId: number | null; + teamId: number | null; + eventLength: number | null; + timeStatus: string | null; + eventParentId: number | null; + userEmail: string | null; + username: string | null; +}; +export type CalendarCache = { + key: string; + value: unknown; + expiresAt: Timestamp; + credentialId: number; +}; +export type Credential = { + id: Generated; + type: string; + key: unknown; + userId: number | null; + teamId: number | null; + appId: string | null; + subscriptionId: string | null; + paymentStatus: string | null; + billingCycleStart: number | null; + invalid: Generated; +}; +export type Deployment = { + /** + * This is a single row table, so we use a fixed id + */ + id: Generated; + logo: string | null; + /** + * @zod.custom(imports.DeploymentTheme) + */ + theme: unknown | null; + licenseKey: string | null; + agreedLicenseAt: Timestamp | null; +}; +export type DestinationCalendar = { + id: Generated; + integration: string; + externalId: string; + userId: number | null; + eventTypeId: number | null; + credentialId: number | null; +}; +export type EventType = { + id: Generated; + /** + * @zod.min(1) + */ + title: string; + /** + * @zod.custom(imports.eventTypeSlug) + */ + slug: string; + description: string | null; + position: Generated; + /** + * @zod.custom(imports.eventTypeLocations) + */ + locations: unknown | null; + /** + * @zod.min(1) + */ + length: number; + offsetStart: Generated; + hidden: Generated; + userId: number | null; + profileId: number | null; + teamId: number | null; + eventName: string | null; + parentId: number | null; + /** + * @zod.custom(imports.eventTypeBookingFields) + */ + bookingFields: unknown | null; + timeZone: string | null; + periodType: Generated; + /** + * @zod.custom(imports.coerceToDate) + */ + periodStartDate: Timestamp | null; + /** + * @zod.custom(imports.coerceToDate) + */ + periodEndDate: Timestamp | null; + periodDays: number | null; + periodCountCalendarDays: boolean | null; + lockTimeZoneToggleOnBookingPage: Generated; + requiresConfirmation: Generated; + requiresBookerEmailVerification: Generated; + /** + * @zod.custom(imports.recurringEventType) + */ + recurringEvent: unknown | null; + disableGuests: Generated; + hideCalendarNotes: Generated; + /** + * @zod.min(0) + */ + minimumBookingNotice: Generated; + beforeEventBuffer: Generated; + afterEventBuffer: Generated; + seatsPerTimeSlot: number | null; + onlyShowFirstAvailableSlot: Generated; + seatsShowAttendees: Generated; + seatsShowAvailabilityCount: Generated; + schedulingType: SchedulingType | null; + scheduleId: number | null; + price: Generated; + currency: Generated; + slotInterval: number | null; + /** + * @zod.custom(imports.EventTypeMetaDataSchema) + */ + metadata: unknown | null; + /** + * @zod.custom(imports.successRedirectUrl) + */ + successRedirectUrl: string | null; + /** + * @zod.custom(imports.intervalLimitsType) + */ + bookingLimits: unknown | null; + /** + * @zod.custom(imports.intervalLimitsType) + */ + durationLimits: unknown | null; + isInstantEvent: Generated; + assignAllTeamMembers: Generated; +}; +export type EventTypeCustomInput = { + id: Generated; + eventTypeId: number; + label: string; + type: EventTypeCustomInputType; + /** + * @zod.custom(imports.customInputOptionSchema) + */ + options: unknown | null; + required: boolean; + placeholder: Generated; +}; +export type Feature = { + slug: string; + enabled: Generated; + description: string | null; + type: Generated; + stale: Generated; + lastUsedAt: Timestamp | null; + createdAt: Generated; + updatedAt: Generated; + updatedBy: number | null; +}; +export type Feedback = { + id: Generated; + date: Generated; + userId: number; + rating: string; + comment: string | null; +}; +export type HashedLink = { + id: Generated; + link: string; + eventTypeId: number; +}; +export type Host = { + userId: number; + eventTypeId: number; + isFixed: Generated; +}; +export type Impersonations = { + id: Generated; + createdAt: Generated; + impersonatedUserId: number; + impersonatedById: number; +}; +export type InstantMeetingToken = { + id: Generated; + token: string; + expires: Timestamp; + teamId: number; + bookingId: number | null; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type Membership = { + id: Generated; + teamId: number; + userId: number; + accepted: Generated; + role: MembershipRole; + disableImpersonation: Generated; +}; +export type OAuthClient = { + clientId: string; + redirectUri: string; + clientSecret: string; + name: string; + logo: string | null; +}; +export type OutOfOfficeEntry = { + id: Generated; + uuid: string; + start: Timestamp; + end: Timestamp; + userId: number; + toUserId: number | null; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type Payment = { + id: Generated; + uid: string; + appId: string | null; + bookingId: number; + amount: number; + fee: number; + currency: string; + success: boolean; + refunded: boolean; + data: unknown; + externalId: string; + paymentOption: Generated; +}; +export type PlatformAuthorizationToken = { + id: string; + platform_oauth_client_id: string; + user_id: number; + created_at: Generated; +}; +export type PlatformOAuthClient = { + id: string; + name: string; + secret: string; + permissions: number; + logo: string | null; + redirect_uris: string[]; + organization_id: number; + created_at: Generated; +}; +export type PlatformOAuthClientToUser = { + A: string; + B: number; +}; +export type Profile = { + id: Generated; + uid: string; + userId: number; + organizationId: number; + username: string; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type RefreshToken = { + id: Generated; + secret: string; + created_at: Generated; + expires_at: Timestamp; + platform_oauth_client_id: string; + user_id: number; +}; +export type ReminderMail = { + id: Generated; + referenceId: number; + reminderType: ReminderType; + elapsedMinutes: number; + createdAt: Generated; +}; +export type ResetPasswordRequest = { + id: string; + createdAt: Generated; + updatedAt: Timestamp; + email: string; + expires: Timestamp; +}; +export type Schedule = { + id: Generated; + userId: number; + name: string; + timeZone: string | null; +}; +export type SelectedCalendar = { + userId: number; + integration: string; + externalId: string; + credentialId: number | null; +}; +export type SelectedSlots = { + id: Generated; + eventTypeId: number; + userId: number; + slotUtcStartDate: Timestamp; + slotUtcEndDate: Timestamp; + uid: string; + releaseAt: Timestamp; + isSeat: Generated; +}; +export type Session = { + id: string; + sessionToken: string; + userId: number; + expires: Timestamp; +}; +export type Team = { + id: Generated; + /** + * @zod.min(1) + */ + name: string; + /** + * @zod.min(1) + */ + slug: string | null; + logo: string | null; + logoUrl: string | null; + calVideoLogo: string | null; + appLogo: string | null; + appIconLogo: string | null; + bio: string | null; + hideBranding: Generated; + isPrivate: Generated; + hideBookATeamMember: Generated; + createdAt: Generated; + /** + * @zod.custom(imports.teamMetadataSchema) + */ + metadata: unknown | null; + theme: string | null; + brandColor: string | null; + darkBrandColor: string | null; + parentId: number | null; + timeFormat: number | null; + timeZone: Generated; + weekStart: Generated; + pendingPayment: Generated; +}; +export type TempOrgRedirect = { + id: Generated; + from: string; + fromOrgId: number; + type: RedirectType; + toUrl: string; + enabled: Generated; + createdAt: Generated; + updatedAt: Timestamp; +}; +export type User = { + id: Generated; + username: string | null; + name: string | null; + /** + * @zod.email() + */ + email: string; + emailVerified: Timestamp | null; + password: string | null; + bio: string | null; + avatar: string | null; + avatarUrl: string | null; + timeZone: Generated; + weekStart: Generated; + startTime: Generated; + endTime: Generated; + bufferTime: Generated; + hideBranding: Generated; + theme: string | null; + created: Generated; + trialEndsAt: Timestamp | null; + defaultScheduleId: number | null; + completedOnboarding: Generated; + locale: string | null; + timeFormat: Generated; + twoFactorSecret: string | null; + twoFactorEnabled: Generated; + backupCodes: string | null; + identityProvider: Generated; + identityProviderId: string | null; + invitedTo: number | null; + brandColor: string | null; + darkBrandColor: string | null; + away: Generated; + allowDynamicBooking: Generated; + allowSEOIndexing: Generated; + receiveMonthlyDigestEmail: Generated; + /** + * @zod.custom(imports.userMetadata) + */ + metadata: unknown | null; + verified: Generated; + role: Generated; + disableImpersonation: Generated; + organizationId: number | null; + locked: Generated; + movedToProfileId: number | null; +}; +export type user_eventtype = { + A: number; + B: number; +}; +export type VerificationToken = { + id: Generated; + identifier: string; + token: string; + expires: Timestamp; + expiresInDays: number | null; + createdAt: Generated; + updatedAt: Timestamp; + teamId: number | null; +}; +export type VerifiedNumber = { + id: Generated; + userId: number | null; + teamId: number | null; + phoneNumber: string; +}; +export type Webhook = { + id: string; + userId: number | null; + teamId: number | null; + eventTypeId: number | null; + /** + * @zod.url() + */ + subscriberUrl: string; + payloadTemplate: string | null; + createdAt: Generated; + active: Generated; + eventTriggers: WebhookTriggerEvents[]; + appId: string | null; + secret: string | null; +}; +export type WebhookScheduledTriggers = { + id: Generated; + jobName: string; + subscriberUrl: string; + payload: string; + startAfter: Timestamp; + retryCount: Generated; + createdAt: Generated; +}; +export type Workflow = { + id: Generated; + position: Generated; + name: string; + userId: number | null; + teamId: number | null; + trigger: WorkflowTriggerEvents; + time: number | null; + timeUnit: TimeUnit | null; +}; +export type WorkflowReminder = { + id: Generated; + bookingUid: string | null; + method: WorkflowMethods; + scheduledDate: Timestamp; + referenceId: string | null; + scheduled: boolean; + workflowStepId: number | null; + cancelled: boolean | null; + seatReferenceId: string | null; + isMandatoryReminder: Generated; +}; +export type WorkflowsOnEventTypes = { + id: Generated; + workflowId: number; + eventTypeId: number; +}; +export type WorkflowStep = { + id: Generated; + stepNumber: number; + action: WorkflowActions; + workflowId: number; + sendTo: string | null; + reminderBody: string | null; + emailSubject: string | null; + template: Generated; + numberRequired: boolean | null; + sender: string | null; + numberVerificationPending: Generated; + includeCalendarEvent: Generated; +}; +export type DB = { + _PlatformOAuthClientToUser: PlatformOAuthClientToUser; + _user_eventtype: user_eventtype; + AccessCode: AccessCode; + Account: Account; + ApiKey: ApiKey; + App: App; + App_RoutingForms_Form: App_RoutingForms_Form; + App_RoutingForms_FormResponse: App_RoutingForms_FormResponse; + Attendee: Attendee; + Availability: Availability; + avatars: Avatar; + Booking: Booking; + BookingReference: BookingReference; + BookingSeat: BookingSeat; + BookingTimeStatus: BookingTimeStatus; + CalendarCache: CalendarCache; + Credential: Credential; + Deployment: Deployment; + DestinationCalendar: DestinationCalendar; + EventType: EventType; + EventTypeCustomInput: EventTypeCustomInput; + Feature: Feature; + Feedback: Feedback; + HashedLink: HashedLink; + Host: Host; + Impersonations: Impersonations; + InstantMeetingToken: InstantMeetingToken; + Membership: Membership; + OAuthClient: OAuthClient; + OutOfOfficeEntry: OutOfOfficeEntry; + Payment: Payment; + platform_access_tokens: AccessToken; + platform_authorization_token: PlatformAuthorizationToken; + platform_oauth_clients: PlatformOAuthClient; + platform_refresh_token: RefreshToken; + Profile: Profile; + ReminderMail: ReminderMail; + ResetPasswordRequest: ResetPasswordRequest; + Schedule: Schedule; + SelectedCalendar: SelectedCalendar; + SelectedSlots: SelectedSlots; + Session: Session; + Team: Team; + TempOrgRedirect: TempOrgRedirect; + users: User; + VerificationToken: VerificationToken; + VerifiedNumber: VerifiedNumber; + Webhook: Webhook; + WebhookScheduledTriggers: WebhookScheduledTriggers; + Workflow: Workflow; + WorkflowReminder: WorkflowReminder; + WorkflowsOnEventTypes: WorkflowsOnEventTypes; + WorkflowStep: WorkflowStep; +}; From 40690bbe5d7d513a6c62e096209b45e409d459e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Mon, 19 Feb 2024 10:58:22 -0700 Subject: [PATCH 09/13] Discard changes to apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts --- .../controllers/slots.controller.e2e-spec.ts | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts diff --git a/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts b/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts deleted file mode 100644 index d1022bcf313194..00000000000000 --- a/apps/api/v2/src/modules/slots/controllers/slots.controller.e2e-spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { bootstrap } from "@/app"; -import { AppModule } from "@/app.module"; -import { HttpExceptionFilter } from "@/filters/http-exception.filter"; -import { PrismaExceptionFilter } from "@/filters/prisma-exception.filter"; -import { SlotsModule } from "@/modules/slots/slots.module"; -import type { INestApplication } from "@nestjs/common"; -import type { NestExpressApplication } from "@nestjs/platform-express"; -import { Test } from "@nestjs/testing"; - -describe("Platform Slots e2e", () => { - let app: INestApplication; - - beforeAll(async () => { - const moduleRef = await Test.createTestingModule({ - providers: [PrismaExceptionFilter, HttpExceptionFilter], - imports: [AppModule, SlotsModule], - }).compile(); - - app = moduleRef.createNestApplication(); - bootstrap(app as NestExpressApplication); - - await app.init(); - }); - - it("should be defined", () => { - expect(app).toBeDefined(); - }); -}); From 979fba9caed21f5b11f7fd45028d793e7ea6da73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Mon, 19 Feb 2024 11:00:32 -0700 Subject: [PATCH 10/13] Discard changes to packages/kysely/types.ts --- packages/kysely/types.ts | 866 --------------------------------------- 1 file changed, 866 deletions(-) delete mode 100644 packages/kysely/types.ts diff --git a/packages/kysely/types.ts b/packages/kysely/types.ts deleted file mode 100644 index 7fa002af77a5e8..00000000000000 --- a/packages/kysely/types.ts +++ /dev/null @@ -1,866 +0,0 @@ -import type { ColumnType } from "kysely"; - -export type Generated = T extends ColumnType - ? ColumnType - : ColumnType; -export type Timestamp = ColumnType; - -export const SchedulingType = { - ROUND_ROBIN: "roundRobin", - COLLECTIVE: "collective", - MANAGED: "managed", -} as const; -export type SchedulingType = (typeof SchedulingType)[keyof typeof SchedulingType]; -export const PeriodType = { - UNLIMITED: "unlimited", - ROLLING: "rolling", - RANGE: "range", -} as const; -export type PeriodType = (typeof PeriodType)[keyof typeof PeriodType]; -export const IdentityProvider = { - CAL: "CAL", - GOOGLE: "GOOGLE", - SAML: "SAML", -} as const; -export type IdentityProvider = (typeof IdentityProvider)[keyof typeof IdentityProvider]; -export const UserPermissionRole = { - USER: "USER", - ADMIN: "ADMIN", -} as const; -export type UserPermissionRole = (typeof UserPermissionRole)[keyof typeof UserPermissionRole]; -export const MembershipRole = { - MEMBER: "MEMBER", - ADMIN: "ADMIN", - OWNER: "OWNER", -} as const; -export type MembershipRole = (typeof MembershipRole)[keyof typeof MembershipRole]; -export const BookingStatus = { - CANCELLED: "cancelled", - ACCEPTED: "accepted", - REJECTED: "rejected", - PENDING: "pending", - AWAITING_HOST: "awaiting_host", -} as const; -export type BookingStatus = (typeof BookingStatus)[keyof typeof BookingStatus]; -export const EventTypeCustomInputType = { - TEXT: "text", - TEXTLONG: "textLong", - NUMBER: "number", - BOOL: "bool", - RADIO: "radio", - PHONE: "phone", -} as const; -export type EventTypeCustomInputType = - (typeof EventTypeCustomInputType)[keyof typeof EventTypeCustomInputType]; -export const ReminderType = { - PENDING_BOOKING_CONFIRMATION: "PENDING_BOOKING_CONFIRMATION", -} as const; -export type ReminderType = (typeof ReminderType)[keyof typeof ReminderType]; -export const PaymentOption = { - ON_BOOKING: "ON_BOOKING", - HOLD: "HOLD", -} as const; -export type PaymentOption = (typeof PaymentOption)[keyof typeof PaymentOption]; -export const WebhookTriggerEvents = { - BOOKING_CREATED: "BOOKING_CREATED", - BOOKING_PAYMENT_INITIATED: "BOOKING_PAYMENT_INITIATED", - BOOKING_PAID: "BOOKING_PAID", - BOOKING_RESCHEDULED: "BOOKING_RESCHEDULED", - BOOKING_REQUESTED: "BOOKING_REQUESTED", - BOOKING_CANCELLED: "BOOKING_CANCELLED", - BOOKING_REJECTED: "BOOKING_REJECTED", - FORM_SUBMITTED: "FORM_SUBMITTED", - MEETING_ENDED: "MEETING_ENDED", - MEETING_STARTED: "MEETING_STARTED", - RECORDING_READY: "RECORDING_READY", - INSTANT_MEETING: "INSTANT_MEETING", -} as const; -export type WebhookTriggerEvents = (typeof WebhookTriggerEvents)[keyof typeof WebhookTriggerEvents]; -export const AppCategories = { - calendar: "calendar", - messaging: "messaging", - other: "other", - payment: "payment", - video: "video", - web3: "web3", - automation: "automation", - analytics: "analytics", - conferencing: "conferencing", - crm: "crm", -} as const; -export type AppCategories = (typeof AppCategories)[keyof typeof AppCategories]; -export const WorkflowTriggerEvents = { - BEFORE_EVENT: "BEFORE_EVENT", - EVENT_CANCELLED: "EVENT_CANCELLED", - NEW_EVENT: "NEW_EVENT", - AFTER_EVENT: "AFTER_EVENT", - RESCHEDULE_EVENT: "RESCHEDULE_EVENT", -} as const; -export type WorkflowTriggerEvents = (typeof WorkflowTriggerEvents)[keyof typeof WorkflowTriggerEvents]; -export const WorkflowActions = { - EMAIL_HOST: "EMAIL_HOST", - EMAIL_ATTENDEE: "EMAIL_ATTENDEE", - SMS_ATTENDEE: "SMS_ATTENDEE", - SMS_NUMBER: "SMS_NUMBER", - EMAIL_ADDRESS: "EMAIL_ADDRESS", - WHATSAPP_ATTENDEE: "WHATSAPP_ATTENDEE", - WHATSAPP_NUMBER: "WHATSAPP_NUMBER", -} as const; -export type WorkflowActions = (typeof WorkflowActions)[keyof typeof WorkflowActions]; -export const TimeUnit = { - DAY: "day", - HOUR: "hour", - MINUTE: "minute", -} as const; -export type TimeUnit = (typeof TimeUnit)[keyof typeof TimeUnit]; -export const WorkflowTemplates = { - REMINDER: "REMINDER", - CUSTOM: "CUSTOM", - CANCELLED: "CANCELLED", - RESCHEDULED: "RESCHEDULED", - COMPLETED: "COMPLETED", -} as const; -export type WorkflowTemplates = (typeof WorkflowTemplates)[keyof typeof WorkflowTemplates]; -export const WorkflowMethods = { - EMAIL: "EMAIL", - SMS: "SMS", - WHATSAPP: "WHATSAPP", -} as const; -export type WorkflowMethods = (typeof WorkflowMethods)[keyof typeof WorkflowMethods]; -export const FeatureType = { - RELEASE: "RELEASE", - EXPERIMENT: "EXPERIMENT", - OPERATIONAL: "OPERATIONAL", - KILL_SWITCH: "KILL_SWITCH", - PERMISSION: "PERMISSION", -} as const; -export type FeatureType = (typeof FeatureType)[keyof typeof FeatureType]; -export const AccessScope = { - READ_BOOKING: "READ_BOOKING", - READ_PROFILE: "READ_PROFILE", -} as const; -export type AccessScope = (typeof AccessScope)[keyof typeof AccessScope]; -export const RedirectType = { - UserEventType: "user-event-type", - TeamEventType: "team-event-type", - User: "user", - Team: "team", -} as const; -export type RedirectType = (typeof RedirectType)[keyof typeof RedirectType]; -export type AccessCode = { - id: Generated; - code: string; - clientId: string | null; - expiresAt: Timestamp; - scopes: AccessScope[]; - userId: number | null; - teamId: number | null; -}; -export type AccessToken = { - id: Generated; - secret: string; - created_at: Generated; - expires_at: Timestamp; - platform_oauth_client_id: string; - user_id: number; -}; -export type Account = { - id: string; - userId: number; - type: string; - provider: string; - providerAccountId: string; - refresh_token: string | null; - access_token: string | null; - expires_at: number | null; - token_type: string | null; - scope: string | null; - id_token: string | null; - session_state: string | null; -}; -export type ApiKey = { - id: string; - userId: number; - teamId: number | null; - note: string | null; - createdAt: Generated; - expiresAt: Timestamp | null; - lastUsedAt: Timestamp | null; - hashedKey: string; - appId: string | null; -}; -export type App = { - slug: string; - dirName: string; - keys: unknown | null; - categories: AppCategories[]; - createdAt: Generated; - updatedAt: Timestamp; - enabled: Generated; -}; -export type App_RoutingForms_Form = { - id: string; - description: string | null; - position: Generated; - routes: unknown | null; - createdAt: Generated; - updatedAt: Timestamp; - name: string; - fields: unknown | null; - userId: number; - teamId: number | null; - disabled: Generated; - /** - * @zod.custom(imports.RoutingFormSettings) - */ - settings: unknown | null; -}; -export type App_RoutingForms_FormResponse = { - id: Generated; - formFillerId: string; - formId: string; - response: unknown; - createdAt: Generated; -}; -export type Attendee = { - id: Generated; - email: string; - name: string; - timeZone: string; - locale: Generated; - bookingId: number | null; -}; -export type Availability = { - id: Generated; - userId: number | null; - eventTypeId: number | null; - days: number[]; - startTime: Timestamp; - endTime: Timestamp; - date: Timestamp | null; - scheduleId: number | null; -}; -export type Avatar = { - teamId: Generated; - userId: Generated; - data: string; - objectKey: string; -}; -export type Booking = { - id: Generated; - uid: string; - userId: number | null; - eventTypeId: number | null; - title: string; - description: string | null; - customInputs: unknown | null; - /** - * @zod.custom(imports.bookingResponses) - */ - responses: unknown | null; - startTime: Timestamp; - endTime: Timestamp; - location: string | null; - createdAt: Generated; - updatedAt: Timestamp | null; - status: Generated; - paid: Generated; - destinationCalendarId: number | null; - cancellationReason: string | null; - rejectionReason: string | null; - dynamicEventSlugRef: string | null; - dynamicGroupSlugRef: string | null; - rescheduled: boolean | null; - fromReschedule: string | null; - recurringEventId: string | null; - smsReminderNumber: string | null; - scheduledJobs: string[]; - /** - * @zod.custom(imports.bookingMetadataSchema) - */ - metadata: unknown | null; - isRecorded: Generated; - iCalUID: Generated; - iCalSequence: Generated; -}; -export type BookingReference = { - id: Generated; - /** - * @zod.min(1) - */ - type: string; - /** - * @zod.min(1) - */ - uid: string; - meetingId: string | null; - thirdPartyRecurringEventId: string | null; - meetingPassword: string | null; - meetingUrl: string | null; - bookingId: number | null; - externalCalendarId: string | null; - deleted: boolean | null; - credentialId: number | null; -}; -export type BookingSeat = { - id: Generated; - referenceUid: string; - bookingId: number; - attendeeId: number; - /** - * @zod.custom(imports.bookingSeatDataSchema) - */ - data: unknown | null; -}; -export type BookingTimeStatus = { - id: number; - uid: string | null; - eventTypeId: number | null; - title: string | null; - description: string | null; - startTime: Timestamp | null; - endTime: Timestamp | null; - createdAt: Timestamp | null; - location: string | null; - paid: boolean | null; - status: BookingStatus | null; - rescheduled: boolean | null; - userId: number | null; - teamId: number | null; - eventLength: number | null; - timeStatus: string | null; - eventParentId: number | null; - userEmail: string | null; - username: string | null; -}; -export type CalendarCache = { - key: string; - value: unknown; - expiresAt: Timestamp; - credentialId: number; -}; -export type Credential = { - id: Generated; - type: string; - key: unknown; - userId: number | null; - teamId: number | null; - appId: string | null; - subscriptionId: string | null; - paymentStatus: string | null; - billingCycleStart: number | null; - invalid: Generated; -}; -export type Deployment = { - /** - * This is a single row table, so we use a fixed id - */ - id: Generated; - logo: string | null; - /** - * @zod.custom(imports.DeploymentTheme) - */ - theme: unknown | null; - licenseKey: string | null; - agreedLicenseAt: Timestamp | null; -}; -export type DestinationCalendar = { - id: Generated; - integration: string; - externalId: string; - userId: number | null; - eventTypeId: number | null; - credentialId: number | null; -}; -export type EventType = { - id: Generated; - /** - * @zod.min(1) - */ - title: string; - /** - * @zod.custom(imports.eventTypeSlug) - */ - slug: string; - description: string | null; - position: Generated; - /** - * @zod.custom(imports.eventTypeLocations) - */ - locations: unknown | null; - /** - * @zod.min(1) - */ - length: number; - offsetStart: Generated; - hidden: Generated; - userId: number | null; - profileId: number | null; - teamId: number | null; - eventName: string | null; - parentId: number | null; - /** - * @zod.custom(imports.eventTypeBookingFields) - */ - bookingFields: unknown | null; - timeZone: string | null; - periodType: Generated; - /** - * @zod.custom(imports.coerceToDate) - */ - periodStartDate: Timestamp | null; - /** - * @zod.custom(imports.coerceToDate) - */ - periodEndDate: Timestamp | null; - periodDays: number | null; - periodCountCalendarDays: boolean | null; - lockTimeZoneToggleOnBookingPage: Generated; - requiresConfirmation: Generated; - requiresBookerEmailVerification: Generated; - /** - * @zod.custom(imports.recurringEventType) - */ - recurringEvent: unknown | null; - disableGuests: Generated; - hideCalendarNotes: Generated; - /** - * @zod.min(0) - */ - minimumBookingNotice: Generated; - beforeEventBuffer: Generated; - afterEventBuffer: Generated; - seatsPerTimeSlot: number | null; - onlyShowFirstAvailableSlot: Generated; - seatsShowAttendees: Generated; - seatsShowAvailabilityCount: Generated; - schedulingType: SchedulingType | null; - scheduleId: number | null; - price: Generated; - currency: Generated; - slotInterval: number | null; - /** - * @zod.custom(imports.EventTypeMetaDataSchema) - */ - metadata: unknown | null; - /** - * @zod.custom(imports.successRedirectUrl) - */ - successRedirectUrl: string | null; - /** - * @zod.custom(imports.intervalLimitsType) - */ - bookingLimits: unknown | null; - /** - * @zod.custom(imports.intervalLimitsType) - */ - durationLimits: unknown | null; - isInstantEvent: Generated; - assignAllTeamMembers: Generated; -}; -export type EventTypeCustomInput = { - id: Generated; - eventTypeId: number; - label: string; - type: EventTypeCustomInputType; - /** - * @zod.custom(imports.customInputOptionSchema) - */ - options: unknown | null; - required: boolean; - placeholder: Generated; -}; -export type Feature = { - slug: string; - enabled: Generated; - description: string | null; - type: Generated; - stale: Generated; - lastUsedAt: Timestamp | null; - createdAt: Generated; - updatedAt: Generated; - updatedBy: number | null; -}; -export type Feedback = { - id: Generated; - date: Generated; - userId: number; - rating: string; - comment: string | null; -}; -export type HashedLink = { - id: Generated; - link: string; - eventTypeId: number; -}; -export type Host = { - userId: number; - eventTypeId: number; - isFixed: Generated; -}; -export type Impersonations = { - id: Generated; - createdAt: Generated; - impersonatedUserId: number; - impersonatedById: number; -}; -export type InstantMeetingToken = { - id: Generated; - token: string; - expires: Timestamp; - teamId: number; - bookingId: number | null; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type Membership = { - id: Generated; - teamId: number; - userId: number; - accepted: Generated; - role: MembershipRole; - disableImpersonation: Generated; -}; -export type OAuthClient = { - clientId: string; - redirectUri: string; - clientSecret: string; - name: string; - logo: string | null; -}; -export type OutOfOfficeEntry = { - id: Generated; - uuid: string; - start: Timestamp; - end: Timestamp; - userId: number; - toUserId: number | null; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type Payment = { - id: Generated; - uid: string; - appId: string | null; - bookingId: number; - amount: number; - fee: number; - currency: string; - success: boolean; - refunded: boolean; - data: unknown; - externalId: string; - paymentOption: Generated; -}; -export type PlatformAuthorizationToken = { - id: string; - platform_oauth_client_id: string; - user_id: number; - created_at: Generated; -}; -export type PlatformOAuthClient = { - id: string; - name: string; - secret: string; - permissions: number; - logo: string | null; - redirect_uris: string[]; - organization_id: number; - created_at: Generated; -}; -export type PlatformOAuthClientToUser = { - A: string; - B: number; -}; -export type Profile = { - id: Generated; - uid: string; - userId: number; - organizationId: number; - username: string; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type RefreshToken = { - id: Generated; - secret: string; - created_at: Generated; - expires_at: Timestamp; - platform_oauth_client_id: string; - user_id: number; -}; -export type ReminderMail = { - id: Generated; - referenceId: number; - reminderType: ReminderType; - elapsedMinutes: number; - createdAt: Generated; -}; -export type ResetPasswordRequest = { - id: string; - createdAt: Generated; - updatedAt: Timestamp; - email: string; - expires: Timestamp; -}; -export type Schedule = { - id: Generated; - userId: number; - name: string; - timeZone: string | null; -}; -export type SelectedCalendar = { - userId: number; - integration: string; - externalId: string; - credentialId: number | null; -}; -export type SelectedSlots = { - id: Generated; - eventTypeId: number; - userId: number; - slotUtcStartDate: Timestamp; - slotUtcEndDate: Timestamp; - uid: string; - releaseAt: Timestamp; - isSeat: Generated; -}; -export type Session = { - id: string; - sessionToken: string; - userId: number; - expires: Timestamp; -}; -export type Team = { - id: Generated; - /** - * @zod.min(1) - */ - name: string; - /** - * @zod.min(1) - */ - slug: string | null; - logo: string | null; - logoUrl: string | null; - calVideoLogo: string | null; - appLogo: string | null; - appIconLogo: string | null; - bio: string | null; - hideBranding: Generated; - isPrivate: Generated; - hideBookATeamMember: Generated; - createdAt: Generated; - /** - * @zod.custom(imports.teamMetadataSchema) - */ - metadata: unknown | null; - theme: string | null; - brandColor: string | null; - darkBrandColor: string | null; - parentId: number | null; - timeFormat: number | null; - timeZone: Generated; - weekStart: Generated; - pendingPayment: Generated; -}; -export type TempOrgRedirect = { - id: Generated; - from: string; - fromOrgId: number; - type: RedirectType; - toUrl: string; - enabled: Generated; - createdAt: Generated; - updatedAt: Timestamp; -}; -export type User = { - id: Generated; - username: string | null; - name: string | null; - /** - * @zod.email() - */ - email: string; - emailVerified: Timestamp | null; - password: string | null; - bio: string | null; - avatar: string | null; - avatarUrl: string | null; - timeZone: Generated; - weekStart: Generated; - startTime: Generated; - endTime: Generated; - bufferTime: Generated; - hideBranding: Generated; - theme: string | null; - created: Generated; - trialEndsAt: Timestamp | null; - defaultScheduleId: number | null; - completedOnboarding: Generated; - locale: string | null; - timeFormat: Generated; - twoFactorSecret: string | null; - twoFactorEnabled: Generated; - backupCodes: string | null; - identityProvider: Generated; - identityProviderId: string | null; - invitedTo: number | null; - brandColor: string | null; - darkBrandColor: string | null; - away: Generated; - allowDynamicBooking: Generated; - allowSEOIndexing: Generated; - receiveMonthlyDigestEmail: Generated; - /** - * @zod.custom(imports.userMetadata) - */ - metadata: unknown | null; - verified: Generated; - role: Generated; - disableImpersonation: Generated; - organizationId: number | null; - locked: Generated; - movedToProfileId: number | null; -}; -export type user_eventtype = { - A: number; - B: number; -}; -export type VerificationToken = { - id: Generated; - identifier: string; - token: string; - expires: Timestamp; - expiresInDays: number | null; - createdAt: Generated; - updatedAt: Timestamp; - teamId: number | null; -}; -export type VerifiedNumber = { - id: Generated; - userId: number | null; - teamId: number | null; - phoneNumber: string; -}; -export type Webhook = { - id: string; - userId: number | null; - teamId: number | null; - eventTypeId: number | null; - /** - * @zod.url() - */ - subscriberUrl: string; - payloadTemplate: string | null; - createdAt: Generated; - active: Generated; - eventTriggers: WebhookTriggerEvents[]; - appId: string | null; - secret: string | null; -}; -export type WebhookScheduledTriggers = { - id: Generated; - jobName: string; - subscriberUrl: string; - payload: string; - startAfter: Timestamp; - retryCount: Generated; - createdAt: Generated; -}; -export type Workflow = { - id: Generated; - position: Generated; - name: string; - userId: number | null; - teamId: number | null; - trigger: WorkflowTriggerEvents; - time: number | null; - timeUnit: TimeUnit | null; -}; -export type WorkflowReminder = { - id: Generated; - bookingUid: string | null; - method: WorkflowMethods; - scheduledDate: Timestamp; - referenceId: string | null; - scheduled: boolean; - workflowStepId: number | null; - cancelled: boolean | null; - seatReferenceId: string | null; - isMandatoryReminder: Generated; -}; -export type WorkflowsOnEventTypes = { - id: Generated; - workflowId: number; - eventTypeId: number; -}; -export type WorkflowStep = { - id: Generated; - stepNumber: number; - action: WorkflowActions; - workflowId: number; - sendTo: string | null; - reminderBody: string | null; - emailSubject: string | null; - template: Generated; - numberRequired: boolean | null; - sender: string | null; - numberVerificationPending: Generated; - includeCalendarEvent: Generated; -}; -export type DB = { - _PlatformOAuthClientToUser: PlatformOAuthClientToUser; - _user_eventtype: user_eventtype; - AccessCode: AccessCode; - Account: Account; - ApiKey: ApiKey; - App: App; - App_RoutingForms_Form: App_RoutingForms_Form; - App_RoutingForms_FormResponse: App_RoutingForms_FormResponse; - Attendee: Attendee; - Availability: Availability; - avatars: Avatar; - Booking: Booking; - BookingReference: BookingReference; - BookingSeat: BookingSeat; - BookingTimeStatus: BookingTimeStatus; - CalendarCache: CalendarCache; - Credential: Credential; - Deployment: Deployment; - DestinationCalendar: DestinationCalendar; - EventType: EventType; - EventTypeCustomInput: EventTypeCustomInput; - Feature: Feature; - Feedback: Feedback; - HashedLink: HashedLink; - Host: Host; - Impersonations: Impersonations; - InstantMeetingToken: InstantMeetingToken; - Membership: Membership; - OAuthClient: OAuthClient; - OutOfOfficeEntry: OutOfOfficeEntry; - Payment: Payment; - platform_access_tokens: AccessToken; - platform_authorization_token: PlatformAuthorizationToken; - platform_oauth_clients: PlatformOAuthClient; - platform_refresh_token: RefreshToken; - Profile: Profile; - ReminderMail: ReminderMail; - ResetPasswordRequest: ResetPasswordRequest; - Schedule: Schedule; - SelectedCalendar: SelectedCalendar; - SelectedSlots: SelectedSlots; - Session: Session; - Team: Team; - TempOrgRedirect: TempOrgRedirect; - users: User; - VerificationToken: VerificationToken; - VerifiedNumber: VerifiedNumber; - Webhook: Webhook; - WebhookScheduledTriggers: WebhookScheduledTriggers; - Workflow: Workflow; - WorkflowReminder: WorkflowReminder; - WorkflowsOnEventTypes: WorkflowsOnEventTypes; - WorkflowStep: WorkflowStep; -}; From e342c8a5c3ccbe228262f35b9aa3486b1899b311 Mon Sep 17 00:00:00 2001 From: exception Date: Mon, 19 Feb 2024 15:53:29 -0300 Subject: [PATCH 11/13] fix: build --- packages/features/ee/organizations/pages/organization.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/features/ee/organizations/pages/organization.tsx b/packages/features/ee/organizations/pages/organization.tsx index 55dd42a061c184..0699101f40978e 100644 --- a/packages/features/ee/organizations/pages/organization.tsx +++ b/packages/features/ee/organizations/pages/organization.tsx @@ -6,7 +6,7 @@ import { MembershipRole } from "@calcom/prisma/client"; export const getServerSideProps = async ({ req, res }: GetServerSidePropsContext) => { const prisma = await import("@calcom/prisma").then((mod) => mod.default); - const organizationsEnabled = await getFeatureFlag(prisma, "orgnizations"); + const organizationsEnabled = await getFeatureFlag(prisma, "organizations"); // Check if organizations are enabled if (!organizationsEnabled) { return { From bab549289708de2364213b9ac2588ad83ef7f199 Mon Sep 17 00:00:00 2001 From: exception Date: Tue, 20 Feb 2024 10:10:16 -0300 Subject: [PATCH 12/13] chore: unit --- packages/app-store/googlecalendar/lib/CalendarService.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/app-store/googlecalendar/lib/CalendarService.test.ts b/packages/app-store/googlecalendar/lib/CalendarService.test.ts index 8cf8f5b247930f..671ffc9f2c5831 100644 --- a/packages/app-store/googlecalendar/lib/CalendarService.test.ts +++ b/packages/app-store/googlecalendar/lib/CalendarService.test.ts @@ -12,6 +12,7 @@ vi.mock("@calcom/features/flags/server/utils", () => ({ getFeatureFlagMap: vi.fn().mockResolvedValue({ "calendar-cache": true, }), + getFeatureFlag: vi.fn().mockImplementation((flagName, _prisma) => flagName === "calendar-cache"), })); vi.mock("./getGoogleAppKeys", () => ({ From d29f2dd74f8e80565d3d19aa04e63350220f20c2 Mon Sep 17 00:00:00 2001 From: exception Date: Tue, 20 Feb 2024 10:28:21 -0300 Subject: [PATCH 13/13] chore: unit --- .../app-store/googlecalendar/lib/CalendarService.test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/app-store/googlecalendar/lib/CalendarService.test.ts b/packages/app-store/googlecalendar/lib/CalendarService.test.ts index 671ffc9f2c5831..776ac6d63e1589 100644 --- a/packages/app-store/googlecalendar/lib/CalendarService.test.ts +++ b/packages/app-store/googlecalendar/lib/CalendarService.test.ts @@ -9,10 +9,7 @@ afterEach(() => { }); vi.mock("@calcom/features/flags/server/utils", () => ({ - getFeatureFlagMap: vi.fn().mockResolvedValue({ - "calendar-cache": true, - }), - getFeatureFlag: vi.fn().mockImplementation((flagName, _prisma) => flagName === "calendar-cache"), + getFeatureFlag: vi.fn().mockReturnValue(true), })); vi.mock("./getGoogleAppKeys", () => ({