Files
stats/packages/trpc/src/routers/integration.ts
2024-10-03 20:48:37 +02:00

143 lines
3.8 KiB
TypeScript

import { z } from 'zod';
import { BASE_INTEGRATIONS, db } from '@openpanel/db';
import { getSlackInstallUrl } from '@openpanel/integrations/src/slack';
import {
type ISlackConfig,
zCreateDiscordIntegration,
zCreateSlackIntegration,
zCreateWebhookIntegration,
} from '@openpanel/validation';
import { getOrganizationAccessCached } from '../access';
import { TRPCAccessError } from '../errors';
import { createTRPCRouter, protectedProcedure } from '../trpc';
export const integrationRouter = createTRPCRouter({
get: protectedProcedure
.input(z.object({ id: z.string() }))
.query(async ({ input, ctx }) => {
const integration = await db.integration.findUniqueOrThrow({
where: {
id: input.id,
},
});
const access = await getOrganizationAccessCached({
userId: ctx.session.userId,
organizationId: integration.organizationId,
});
if (!access) {
throw TRPCAccessError('You do not have access to this project');
}
return integration;
}),
list: protectedProcedure
.input(z.object({ organizationId: z.string() }))
.query(async ({ input }) => {
const integrations = await db.integration.findMany({
where: {
organizationId: input.organizationId,
config: {
not: {},
},
},
});
return [...BASE_INTEGRATIONS, ...integrations];
}),
createOrUpdateSlack: protectedProcedure
.input(zCreateSlackIntegration)
.mutation(async ({ input }) => {
if (input.id) {
const res = await db.integration.update({
where: {
id: input.id,
organizationId: input.organizationId,
},
data: {
name: input.name,
// This is empty and will be filled by the webhook
config: {} as ISlackConfig,
},
});
return {
...res,
slackInstallUrl: await getSlackInstallUrl({
integrationId: res.id,
organizationId: input.organizationId,
projectId: input.projectId,
}),
};
}
const res = await db.integration.create({
data: {
name: input.name,
organizationId: input.organizationId,
// This is empty and will be filled by the webhook
config: {} as ISlackConfig,
},
});
return {
...res,
slackInstallUrl: await getSlackInstallUrl({
integrationId: res.id,
organizationId: input.organizationId,
projectId: input.projectId,
}),
};
}),
createOrUpdate: protectedProcedure
.input(z.union([zCreateDiscordIntegration, zCreateWebhookIntegration]))
.mutation(async ({ input }) => {
if (input.id) {
return db.integration.update({
where: {
id: input.id,
organizationId: input.organizationId,
},
data: {
name: input.name,
config: input.config,
},
});
}
return db.integration.create({
data: {
name: input.name,
organizationId: input.organizationId,
config: input.config,
},
});
}),
delete: protectedProcedure
.input(z.object({ id: z.string() }))
.mutation(async ({ input: { id }, ctx }) => {
const integration = await db.integration.findUniqueOrThrow({
where: {
id,
},
});
const access = await getOrganizationAccessCached({
userId: ctx.session.userId,
organizationId: integration.organizationId,
});
if (!access) {
throw TRPCAccessError('You do not have access to this project');
}
return db.integration.delete({
where: {
id,
},
});
}),
});