165 lines
4.5 KiB
TypeScript
165 lines
4.5 KiB
TypeScript
|
import { Prisma } from "@prisma/client";
|
||
|
import _ from "lodash";
|
||
|
|
||
|
import { validJson } from "@lib/jsonUtils";
|
||
|
|
||
|
const credentialData = Prisma.validator<Prisma.CredentialArgs>()({
|
||
|
select: { id: true, type: true },
|
||
|
});
|
||
|
|
||
|
type CredentialData = Prisma.CredentialGetPayload<typeof credentialData>;
|
||
|
|
||
|
export type Integration = {
|
||
|
installed: boolean;
|
||
|
type:
|
||
|
| "google_calendar"
|
||
|
| "office365_calendar"
|
||
|
| "zoom_video"
|
||
|
| "daily_video"
|
||
|
| "tandem_video"
|
||
|
| "caldav_calendar"
|
||
|
| "apple_calendar"
|
||
|
| "stripe_payment"
|
||
|
| "jitsi_video"
|
||
|
| "huddle01_video"
|
||
|
| "metamask_web3";
|
||
|
title: string;
|
||
|
imageSrc: string;
|
||
|
description: string;
|
||
|
variant: "calendar" | "conferencing" | "payment" | "web3";
|
||
|
};
|
||
|
|
||
|
export const ALL_INTEGRATIONS = [
|
||
|
{
|
||
|
installed: !!(process.env.GOOGLE_API_CREDENTIALS && validJson(process.env.GOOGLE_API_CREDENTIALS)),
|
||
|
type: "google_calendar",
|
||
|
title: "Google Calendar",
|
||
|
imageSrc: "integrations/google-calendar.svg",
|
||
|
description: "For personal and business calendars",
|
||
|
variant: "calendar",
|
||
|
},
|
||
|
{
|
||
|
installed: !!(process.env.MS_GRAPH_CLIENT_ID && process.env.MS_GRAPH_CLIENT_SECRET),
|
||
|
type: "office365_calendar",
|
||
|
title: "Office 365 / Outlook.com Calendar",
|
||
|
imageSrc: "integrations/outlook.svg",
|
||
|
description: "For personal and business calendars",
|
||
|
variant: "calendar",
|
||
|
},
|
||
|
{
|
||
|
installed: !!(process.env.ZOOM_CLIENT_ID && process.env.ZOOM_CLIENT_SECRET),
|
||
|
type: "zoom_video",
|
||
|
title: "Zoom",
|
||
|
imageSrc: "integrations/zoom.svg",
|
||
|
description: "Video Conferencing",
|
||
|
variant: "conferencing",
|
||
|
},
|
||
|
{
|
||
|
installed: !!process.env.DAILY_API_KEY,
|
||
|
type: "daily_video",
|
||
|
title: "Daily.co Video",
|
||
|
imageSrc: "integrations/daily.svg",
|
||
|
description: "Video Conferencing",
|
||
|
variant: "conferencing",
|
||
|
},
|
||
|
{
|
||
|
installed: true,
|
||
|
type: "jitsi_video",
|
||
|
title: "Jitsi Meet",
|
||
|
imageSrc: "integrations/jitsi.svg",
|
||
|
description: "Video Conferencing",
|
||
|
variant: "conferencing",
|
||
|
},
|
||
|
{
|
||
|
installed: true,
|
||
|
type: "huddle01_video",
|
||
|
title: "Huddle01",
|
||
|
imageSrc: "integrations/huddle.svg",
|
||
|
description: "Video Conferencing",
|
||
|
variant: "conferencing",
|
||
|
},
|
||
|
{
|
||
|
installed: !!(process.env.TANDEM_CLIENT_ID && process.env.TANDEM_CLIENT_SECRET),
|
||
|
type: "tandem_video",
|
||
|
title: "Tandem Video",
|
||
|
imageSrc: "integrations/tandem.svg",
|
||
|
description: "Virtual Office | Video Conferencing",
|
||
|
variant: "conferencing",
|
||
|
},
|
||
|
{
|
||
|
installed: true,
|
||
|
type: "caldav_calendar",
|
||
|
title: "CalDav Server",
|
||
|
imageSrc: "integrations/caldav.svg",
|
||
|
description: "For personal and business calendars",
|
||
|
variant: "calendar",
|
||
|
},
|
||
|
{
|
||
|
installed: true,
|
||
|
type: "apple_calendar",
|
||
|
title: "Apple Calendar",
|
||
|
imageSrc: "integrations/apple-calendar.svg",
|
||
|
description: "For personal and business calendars",
|
||
|
variant: "calendar",
|
||
|
},
|
||
|
{
|
||
|
installed: !!(
|
||
|
process.env.STRIPE_CLIENT_ID &&
|
||
|
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY &&
|
||
|
process.env.STRIPE_PRIVATE_KEY
|
||
|
),
|
||
|
type: "stripe_payment",
|
||
|
title: "Stripe",
|
||
|
imageSrc: "integrations/stripe.svg",
|
||
|
description: "Collect payments",
|
||
|
variant: "payment",
|
||
|
},
|
||
|
{
|
||
|
installed: true,
|
||
|
type: "metamask_web3",
|
||
|
title: "Metamask",
|
||
|
imageSrc: "integrations/apple-calendar.svg",
|
||
|
description: "For personal and business calendars",
|
||
|
variant: "web3",
|
||
|
},
|
||
|
] as Integration[];
|
||
|
|
||
|
function getIntegrations(userCredentials: CredentialData[]) {
|
||
|
const integrations = ALL_INTEGRATIONS.map((integration) => {
|
||
|
const credentials = userCredentials
|
||
|
.filter((credential) => credential.type === integration.type)
|
||
|
.map((credential) => _.pick(credential, ["id", "type"])); // ensure we don't leak `key` to frontend
|
||
|
|
||
|
const credential: typeof credentials[number] | null = credentials[0] || null;
|
||
|
return {
|
||
|
...integration,
|
||
|
/**
|
||
|
* @deprecated use `credentials`
|
||
|
*/
|
||
|
credential,
|
||
|
credentials,
|
||
|
};
|
||
|
});
|
||
|
|
||
|
return integrations;
|
||
|
}
|
||
|
|
||
|
export type IntegrationMeta = ReturnType<typeof getIntegrations>;
|
||
|
|
||
|
export function hasIntegration(integrations: IntegrationMeta, type: string): boolean {
|
||
|
return !!integrations.find(
|
||
|
(i) =>
|
||
|
i.type === type &&
|
||
|
!!i.installed &&
|
||
|
(type === "daily_video" ||
|
||
|
type === "jitsi_video" ||
|
||
|
type === "huddle01_video" ||
|
||
|
i.credentials.length > 0)
|
||
|
);
|
||
|
}
|
||
|
export function hasIntegrationInstalled(type: Integration["type"]): boolean {
|
||
|
return ALL_INTEGRATIONS.some((i) => i.type === type && !!i.installed);
|
||
|
}
|
||
|
|
||
|
export default getIntegrations;
|