refactor: Break videoClient into two separate files in app-store and features (#23992)

* getVideoAdapters

* fix
This commit is contained in:
Benny Joo
2025-10-10 07:11:46 -03:00
committed by GitHub
parent 3bcce02b92
commit dbe55f0804
24 changed files with 75 additions and 67 deletions
@@ -3,7 +3,7 @@ import type { NextApiRequest } from "next";
import {
getRecordingsOfCalVideoByRoomName,
getDownloadLinkOfCalVideoByRecordingId,
} from "@calcom/app-store/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
@@ -3,7 +3,7 @@ import type { NextApiRequest } from "next";
import {
getTranscriptsAccessLinkFromRecordingId,
checkIfRoomNameMatchesInRecording,
} from "@calcom/app-store/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
@@ -1,6 +1,6 @@
import type { NextApiRequest } from "next";
import { getAllTranscriptsAccessLinkFromRoomName } from "@calcom/app-store/videoClient";
import { getAllTranscriptsAccessLinkFromRoomName } from "@calcom/features/conferencing/lib/videoClient";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
@@ -9,7 +9,7 @@ import { buildBooking } from "@calcom/lib/test/builder";
import {
getRecordingsOfCalVideoByRoomName,
getDownloadLinkOfCalVideoByRecordingId,
} from "@calcom/app-store/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers";
@@ -22,7 +22,7 @@ type CustomNextApiResponse = NextApiResponse & Response;
const adminUserId = 1;
const memberUserId = 10;
vi.mock("@calcom/app-store/videoClient", () => {
vi.mock("@calcom/features/conferencing/lib/videoClient", () => {
return {
getRecordingsOfCalVideoByRoomName: vi.fn(),
getDownloadLinkOfCalVideoByRecordingId: vi.fn(),
@@ -8,7 +8,7 @@ import { describe, expect, test, vi, afterEach } from "vitest";
import {
getTranscriptsAccessLinkFromRecordingId,
checkIfRoomNameMatchesInRecording,
} from "@calcom/app-store/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
import { buildBooking } from "@calcom/lib/test/builder";
import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers";
@@ -19,7 +19,7 @@ import handler from "../../../../../../pages/api/bookings/[id]/transcripts/[reco
type CustomNextApiRequest = NextApiRequest & Request;
type CustomNextApiResponse = NextApiResponse & Response;
vi.mock("@calcom/app-store/videoClient", () => {
vi.mock("@calcom/features/conferencing/lib/videoClient", () => {
return {
getTranscriptsAccessLinkFromRecordingId: vi.fn(),
checkIfRoomNameMatchesInRecording: vi.fn(),
@@ -6,7 +6,7 @@ import { createMocks } from "node-mocks-http";
import { describe, expect, test, vi, afterEach } from "vitest";
import { buildBooking } from "@calcom/lib/test/builder";
import { getAllTranscriptsAccessLinkFromRoomName } from "@calcom/app-store/videoClient";
import { getAllTranscriptsAccessLinkFromRoomName } from "@calcom/features/conferencing/lib/videoClient";
import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers";
@@ -16,7 +16,7 @@ import handler from "../../../../../pages/api/bookings/[id]/transcripts/_get";
type CustomNextApiRequest = NextApiRequest & Request;
type CustomNextApiResponse = NextApiResponse & Response;
vi.mock("@calcom/app-store/videoClient", () => {
vi.mock("@calcom/features/conferencing/lib/videoClient", () => {
return {
getAllTranscriptsAccessLinkFromRoomName: vi.fn(),
};
@@ -17,7 +17,7 @@ import { safeStringify } from "@calcom/lib/safeStringify";
import {
getAllTranscriptsAccessLinkFromMeetingId,
submitBatchProcessorTranscriptionJob,
} from "@calcom/app-store/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
import { generateVideoToken } from "@calcom/lib/videoTokens";
import prisma from "@calcom/prisma";
import { getBooking } from "@calcom/web/lib/daily-webhook/getBooking";
@@ -1,12 +1,12 @@
import { NextResponse } from "next/server";
import { describe, expect, test, vi, afterEach } from "vitest";
import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/app-store/videoClient";
import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/features/conferencing/lib/videoClient";
import { verifyVideoToken } from "@calcom/lib/videoTokens";
import { GET } from "../route";
vi.mock("@calcom/app-store/videoClient", () => ({
vi.mock("@calcom/features/conferencing/lib/videoClient", () => ({
getDownloadLinkOfCalVideoByRecordingId: vi.fn(),
}));
+1 -1
View File
@@ -1,6 +1,6 @@
import { NextResponse } from "next/server";
import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/app-store/videoClient";
import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/features/conferencing/lib/videoClient";
import { verifyVideoToken } from "@calcom/lib/videoTokens";
export async function GET(request: Request) {
+45
View File
@@ -0,0 +1,45 @@
import { VideoApiAdapterMap } from "@calcom/app-store/video.adapters.generated";
import logger from "@calcom/lib/logger";
import { getPiiFreeCredential } from "@calcom/lib/piiFreeData";
import { safeStringify } from "@calcom/lib/safeStringify";
import type { CredentialPayload } from "@calcom/types/Credential";
import type { VideoApiAdapter, VideoApiAdapterFactory } from "@calcom/types/VideoApiAdapter";
const log = logger.getSubLogger({ prefix: ["[app-store] getVideoAdapters"] });
// factory
export const getVideoAdapters = async (withCredentials: CredentialPayload[]): Promise<VideoApiAdapter[]> => {
const videoAdapters: VideoApiAdapter[] = [];
for (const cred of withCredentials) {
const appName = cred.type.split("_").join(""); // Transform `zoom_video` to `zoomvideo`;
log.silly("Getting video adapter for", safeStringify({ appName, cred: getPiiFreeCredential(cred) }));
let videoAdapterImport = VideoApiAdapterMap[appName as keyof typeof VideoApiAdapterMap];
// fallback: transforms zoom_video to zoom
if (!videoAdapterImport) {
const appTypeVariant = cred.type.substring(0, cred.type.lastIndexOf("_"));
log.silly(`Adapter not found for ${appName}, trying fallback ${appTypeVariant}`);
videoAdapterImport = VideoApiAdapterMap[appTypeVariant as keyof typeof VideoApiAdapterMap];
}
if (!videoAdapterImport) {
log.error(`Couldn't get adapter for ${appName}`);
continue;
}
const videoAdapterModule = await videoAdapterImport;
const makeVideoApiAdapter = videoAdapterModule.default as VideoApiAdapterFactory;
if (makeVideoApiAdapter) {
const videoAdapter = makeVideoApiAdapter(cred);
videoAdapters.push(videoAdapter);
} else {
log.error(`App ${appName} doesn't have a default VideoApiAdapter export`);
}
}
return videoAdapters;
};
+1 -1
View File
@@ -6,7 +6,7 @@ import { CalendarEventBuilder } from "@calcom/lib/builders/CalendarEvent/builder
import { CalendarEventDirector } from "@calcom/lib/builders/CalendarEvent/director";
import logger from "@calcom/lib/logger";
import { getTranslation } from "@calcom/lib/server/i18n";
import { deleteMeeting } from "@calcom/app-store/videoClient";
import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
import prisma from "@calcom/prisma";
import type { Booking, BookingReference, User } from "@calcom/prisma/client";
import { BookingStatus } from "@calcom/prisma/enums";
@@ -6,7 +6,7 @@ import { CalendarEventBuilder } from "@calcom/lib/builders/CalendarEvent/builder
import { CalendarEventDirector } from "@calcom/lib/builders/CalendarEvent/director";
import logger from "@calcom/lib/logger";
import { getTranslation } from "@calcom/lib/server/i18n";
import { deleteMeeting } from "@calcom/app-store/videoClient";
import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
import prisma from "@calcom/prisma";
import type { Booking, BookingReference, User } from "@calcom/prisma/client";
import { BookingStatus } from "@calcom/prisma/enums";
@@ -8,8 +8,8 @@ import { FAKE_DAILY_CREDENTIAL } from "@calcom/app-store/dailyvideo/lib/VideoApi
import { appKeysSchema as calVideoKeysSchema } from "@calcom/app-store/dailyvideo/zod";
import { getLocationFromApp, MeetLocationType, MSTeamsLocationType } from "@calcom/app-store/locations";
import getApps from "@calcom/app-store/utils";
import { createMeeting, updateMeeting, deleteMeeting } from "@calcom/app-store/videoClient";
import { createEvent, updateEvent, deleteEvent } from "@calcom/features/calendars/lib/CalendarManager";
import { createMeeting, updateMeeting, deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
import CrmManager from "@calcom/features/crmManager/crmManager";
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
import { getUid } from "@calcom/lib/CalEventParser";
@@ -10,7 +10,7 @@ import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { getTranslation } from "@calcom/lib/server/i18n";
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import { updateMeeting } from "@calcom/app-store/videoClient";
import { updateMeeting } from "@calcom/features/conferencing/lib/videoClient";
import prisma from "@calcom/prisma";
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
import { bookingCancelAttendeeSeatSchema } from "@calcom/prisma/zod-utils";
@@ -2,7 +2,7 @@
import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
import { getAllDelegationCredentialsForUserIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential";
import { getDelegationCredentialOrFindRegularCredential } from "@calcom/app-store/delegationCredential";
import { deleteMeeting } from "@calcom/app-store/videoClient";
import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
import prisma from "@calcom/prisma";
import type { Attendee } from "@calcom/prisma/client";
import { BookingStatus } from "@calcom/prisma/enums";
+1 -1
View File
@@ -1,3 +1,3 @@
# Conferencing related code will live here
- [ ] Maybe migrate `videoClient` here
- [x] Maybe migrate `videoClient` here
@@ -3,7 +3,7 @@ import { v5 as uuidv5 } from "uuid";
import { DailyLocationType } from "@calcom/app-store/constants";
import { getDailyAppKeys } from "@calcom/app-store/dailyvideo/lib/getDailyAppKeys";
import { VideoApiAdapterMap } from "@calcom/app-store/video.adapters.generated";
import { getVideoAdapters } from "@calcom/app-store/getVideoAdapters";
import { sendBrokenIntegrationEmail } from "@calcom/emails";
import { getUid } from "@calcom/lib/CalEventParser";
import logger from "@calcom/lib/logger";
@@ -14,49 +14,12 @@ import type { GetRecordingsResponseSchema, GetAccessLinkResponseSchema } from "@
import type { CalendarEvent, EventBusyDate } from "@calcom/types/Calendar";
import type { CredentialPayload } from "@calcom/types/Credential";
import type { EventResult, PartialReference } from "@calcom/types/EventManager";
import type { VideoApiAdapter, VideoApiAdapterFactory, VideoCallData } from "@calcom/types/VideoApiAdapter";
import type { VideoCallData } from "@calcom/types/VideoApiAdapter";
const log = logger.getSubLogger({ prefix: ["[lib] videoClient"] });
const log = logger.getSubLogger({ prefix: ["[features/conferencing/lib] videoClient"] });
const translator = short();
// factory
const getVideoAdapters = async (withCredentials: CredentialPayload[]): Promise<VideoApiAdapter[]> => {
const videoAdapters: VideoApiAdapter[] = [];
for (const cred of withCredentials) {
const appName = cred.type.split("_").join(""); // Transform `zoom_video` to `zoomvideo`;
log.silly("Getting video adapter for", safeStringify({ appName, cred: getPiiFreeCredential(cred) }));
let videoAdapterImport = VideoApiAdapterMap[appName as keyof typeof VideoApiAdapterMap];
// fallback: transforms zoom_video to zoom
if (!videoAdapterImport) {
const appTypeVariant = cred.type.substring(0, cred.type.lastIndexOf("_"));
log.silly(`Adapter not found for ${appName}, trying fallback ${appTypeVariant}`);
videoAdapterImport = VideoApiAdapterMap[appTypeVariant as keyof typeof VideoApiAdapterMap];
}
if (!videoAdapterImport) {
log.error(`Couldn't get adapter for ${appName}`);
continue;
}
const videoAdapterModule = await videoAdapterImport;
const makeVideoApiAdapter = videoAdapterModule.default as VideoApiAdapterFactory;
if (makeVideoApiAdapter) {
const videoAdapter = makeVideoApiAdapter(cred);
videoAdapters.push(videoAdapter);
} else {
log.error(`App ${appName} doesn't have a default VideoApiAdapter export`);
}
}
return videoAdapters;
};
const getBusyVideoTimes = async (withCredentials: CredentialPayload[]) =>
Promise.all((await getVideoAdapters(withCredentials)).map((c) => c?.getAvailability())).then((results) =>
results.reduce((acc, availability) => acc.concat(availability), [] as (EventBusyDate | undefined)[])
@@ -21,7 +21,7 @@ vi.mock("@calcom/features/notifications/sendNotification", () => ({
sendNotification: vi.fn(),
}));
vi.mock("@calcom/app-store/videoClient", () => ({
vi.mock("@calcom/features/conferencing/lib/videoClient", () => ({
createInstantMeetingWithCalVideo: vi.fn().mockResolvedValue({
type: "daily_video",
id: "MOCK_INSTANT_MEETING_ID",
@@ -2,7 +2,6 @@ import { randomBytes } from "crypto";
import short from "short-uuid";
import { v5 as uuidv5 } from "uuid";
import { createInstantMeetingWithCalVideo } from "@calcom/app-store/videoClient";
import dayjs from "@calcom/dayjs";
import type {
CreateInstantBookingData,
@@ -14,6 +13,7 @@ import { getBookingData } from "@calcom/features/bookings/lib/handleNewBooking/g
import { getCustomInputsResponses } from "@calcom/features/bookings/lib/handleNewBooking/getCustomInputsResponses";
import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBooking/getEventTypesFromDB";
import type { IBookingCreateService } from "@calcom/features/bookings/lib/interfaces/IBookingCreateService";
import { createInstantMeetingWithCalVideo } from "@calcom/features/conferencing/lib/videoClient";
import { getFullName } from "@calcom/features/form-builder/utils";
import { sendNotification } from "@calcom/features/notifications/sendNotification";
import { sendGenericWebhookPayload } from "@calcom/features/webhooks/lib/sendPayload";
+1 -1
View File
@@ -2,4 +2,4 @@ export {
getRecordingsOfCalVideoByRoomName,
getDownloadLinkOfCalVideoByRecordingId,
getAllTranscriptsAccessLinkFromRoomName,
} from "@calcom/app-store/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
@@ -3,10 +3,10 @@ import type { TFunction } from "i18next";
import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
import { getDelegationCredentialOrRegularCredential } from "@calcom/app-store/delegationCredential";
import { getUsersCredentialsIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential";
import { deleteMeeting } from "@calcom/app-store/videoClient";
import dayjs from "@calcom/dayjs";
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails";
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient";
import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
import {
deleteWebhookScheduledTriggers,
@@ -1,4 +1,4 @@
import { getRecordingsOfCalVideoByRoomName } from "@calcom/app-store/videoClient";
import { getRecordingsOfCalVideoByRoomName } from "@calcom/features/conferencing/lib/videoClient";
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
import { TRPCError } from "@trpc/server";
@@ -1,6 +1,6 @@
/// <reference types="@calcom/types/next-auth" />
import { IS_SELF_HOSTED } from "@calcom/lib/constants";
import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/app-store/videoClient";
import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/features/conferencing/lib/videoClient";
import { TRPCError } from "@trpc/server";
+2 -2
View File
@@ -1,9 +1,9 @@
import { beforeEach, vi } from "vitest";
import { mockReset, mockDeep } from "vitest-mock-extended";
import type * as videoClient from "@calcom/app-store/videoClient";
import type * as videoClient from "@calcom/features/conferencing/lib/videoClient";
vi.mock("@calcom/app-store/videoClient", () => videoClientMock);
vi.mock("@calcom/features/conferencing/lib/videoClient", () => videoClientMock);
beforeEach(() => {
mockReset(videoClientMock);