kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
at main 138 lines 3.5 kB view raw
1import { and, eq } from "drizzle-orm"; 2import db from "../../../database"; 3import { externalLinkTable } from "../../../database/schema"; 4 5export type CreateExternalLinkParams = { 6 taskId: string; 7 integrationId: string; 8 resourceType: "issue" | "pull_request" | "branch"; 9 externalId: string; 10 url: string; 11 title?: string | null; 12 metadata?: Record<string, unknown>; 13}; 14 15export type UpdateExternalLinkParams = { 16 title?: string | null; 17 url?: string; 18 metadata?: Record<string, unknown>; 19}; 20 21export async function createExternalLink( 22 params: CreateExternalLinkParams, 23): Promise<{ id: string }> { 24 const result = await db 25 .insert(externalLinkTable) 26 .values({ 27 taskId: params.taskId, 28 integrationId: params.integrationId, 29 resourceType: params.resourceType, 30 externalId: params.externalId, 31 url: params.url, 32 title: params.title ?? null, 33 metadata: params.metadata ? JSON.stringify(params.metadata) : null, 34 }) 35 .returning({ id: externalLinkTable.id }); 36 37 const link = result[0]; 38 if (!link) { 39 throw new Error("Failed to create external link"); 40 } 41 42 return link; 43} 44 45export async function findExternalLink( 46 integrationId: string, 47 resourceType: string, 48 externalId: string, 49) { 50 return db.query.externalLinkTable.findFirst({ 51 where: and( 52 eq(externalLinkTable.integrationId, integrationId), 53 eq(externalLinkTable.resourceType, resourceType), 54 eq(externalLinkTable.externalId, externalId), 55 ), 56 }); 57} 58 59export async function findExternalLinkByTaskAndType( 60 taskId: string, 61 integrationId: string, 62 resourceType: string, 63) { 64 return db.query.externalLinkTable.findFirst({ 65 where: and( 66 eq(externalLinkTable.taskId, taskId), 67 eq(externalLinkTable.integrationId, integrationId), 68 eq(externalLinkTable.resourceType, resourceType), 69 ), 70 }); 71} 72 73export async function findExternalLinksByTask(taskId: string) { 74 return db.query.externalLinkTable.findMany({ 75 where: eq(externalLinkTable.taskId, taskId), 76 with: { 77 integration: true, 78 }, 79 }); 80} 81 82export async function updateExternalLink( 83 id: string, 84 params: UpdateExternalLinkParams, 85) { 86 const updateData: Record<string, unknown> = {}; 87 88 if (params.title !== undefined) { 89 updateData.title = params.title; 90 } 91 if (params.url !== undefined) { 92 updateData.url = params.url; 93 } 94 if (params.metadata !== undefined) { 95 updateData.metadata = JSON.stringify(params.metadata); 96 } 97 98 if (Object.keys(updateData).length === 0) { 99 return; 100 } 101 102 await db 103 .update(externalLinkTable) 104 .set(updateData) 105 .where(eq(externalLinkTable.id, id)); 106} 107 108export async function createOrUpdateExternalLink( 109 params: CreateExternalLinkParams, 110): Promise<{ id: string; created: boolean }> { 111 const existing = await findExternalLink( 112 params.integrationId, 113 params.resourceType, 114 params.externalId, 115 ); 116 117 if (existing) { 118 await updateExternalLink(existing.id, { 119 title: params.title, 120 url: params.url, 121 metadata: params.metadata, 122 }); 123 return { id: existing.id, created: false }; 124 } 125 126 const link = await createExternalLink(params); 127 return { id: link.id, created: true }; 128} 129 130export async function deleteExternalLink(id: string) { 131 await db.delete(externalLinkTable).where(eq(externalLinkTable.id, id)); 132} 133 134export async function getExternalLinksByIntegration(integrationId: string) { 135 return db.query.externalLinkTable.findMany({ 136 where: eq(externalLinkTable.integrationId, integrationId), 137 }); 138}