Files
calendar/packages/app-store/_utils/getEnabledAppsFromCredentials.ts
T
Benny JooGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
3aab13b4da refactor: circular deps between app store and lib [3] (#23742)
* getEnabledAppsFromCredentials

* wip

* wip

* mv more

* fix: update test mocking for PrismockClient in processPaymentRefund.test.ts

- Replace prismaMock with prismock for proper PrismockClient usage
- Update mock data structure to include required fields (id, userId, teamId, etc.)
- Create app and credential records separately to handle PrismockClient limitations
- Replace 'as any' type casting with vi.mocked() for proper type safety
- Adjust test expectations to match PrismockClient's actual return structure
- Add proper cleanup in beforeEach hook for both credential and app records

Fixes failing unit tests after migration from packages/lib to packages/features/bookings/lib/payment

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* publish platform libraries

* fix import

* bump version

* fix apiv2

* publish platform-libraries

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-14 11:24:16 -03:00

86 lines
2.8 KiB
TypeScript

import type { CredentialDataWithTeamName } from "@calcom/app-store/utils";
import { isDelegationCredential } from "@calcom/lib/delegationCredential/clientAndServer";
import { prisma } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import getApps from "../utils";
type EnabledApp = ReturnType<typeof getApps>[number] & { enabled: boolean };
/**
*
* @param credentials - Can be user or team credentials
* @param options
* @param options.where Additional where conditions to filter out apps
* @param options.filterOnCredentials - Only include apps where credentials are present
* @returns A list of enabled app metadata & credentials tied to them
*/
const getEnabledAppsFromCredentials = async (
credentials: CredentialDataWithTeamName[],
options?: {
where?: Prisma.AppWhereInput;
filterOnCredentials?: boolean;
}
) => {
const { where: _where = {}, filterOnCredentials = false } = options || {};
const filterOnIds = {
credentials: {
some: {
OR: [] as Prisma.CredentialWhereInput[],
},
},
} satisfies Prisma.AppWhereInput;
const delegationCredentialsWithAppId = credentials
.filter((credential) => isDelegationCredential({ credentialId: credential.id }))
.filter((credential): credential is typeof credential & { appId: string } => credential.appId !== null);
if (filterOnCredentials) {
const userIds: number[] = [],
teamIds: number[] = [];
for (const credential of credentials) {
if (credential.userId) userIds.push(credential.userId);
if (credential.teamId) teamIds.push(credential.teamId);
}
if (userIds.length) filterOnIds.credentials.some.OR.push({ userId: { in: userIds } });
if (teamIds.length) filterOnIds.credentials.some.OR.push({ teamId: { in: teamIds } });
}
const where: Prisma.AppWhereInput = {
enabled: true,
..._where,
...(filterOnIds.credentials.some.OR.length && filterOnIds),
};
let enabledApps = await prisma.app.findMany({
where,
select: { slug: true, enabled: true },
});
const delegationCredentialSupportedEnabledApps = await prisma.app.findMany({
where: {
enabled: true,
slug: {
in: delegationCredentialsWithAppId.map((credential) => credential.appId),
},
},
select: { slug: true, enabled: true },
});
enabledApps = [...enabledApps, ...delegationCredentialSupportedEnabledApps];
const apps = getApps(credentials, filterOnCredentials);
const filteredApps = apps.reduce((reducedArray, app) => {
const appDbQuery = enabledApps.find((metadata) => metadata.slug === app.slug);
if (appDbQuery?.enabled || app.isGlobal) {
reducedArray.push({ ...app, enabled: true });
}
return reducedArray;
}, [] as EnabledApp[]);
return filteredApps;
};
export default getEnabledAppsFromCredentials;