mirror your GitHub repos to tangled.org automatically
1

Configure Feed

Select the types of activity you want to include in your feed.

at main 4.0 kB View raw
1import { sql } from 'drizzle-orm' 2import { installation, repoMapping, sshKey, userIdentity } from '#server/db/schema' 3import { useDb } from '#server/utils/db' 4import { requireSession } from '#server/utils/server-session' 5 6export interface DashboardRepo { 7 id: number 8 githubRepoId: number 9 githubFullName: string 10 tangledRepoDid: string | null 11 tangledFullName: string | null 12 knot: string | null 13 status: string 14 lastError: string | null 15 disabledAt: string | null 16 lastSyncedRefs: Record<string, string> 17 lastSyncedAt: string | null 18 refCount: number 19} 20 21export interface DashboardPayload { 22 did: string 23 handle: string | null 24 installation: { 25 id: number 26 accountLogin: string 27 accountType: string 28 suspendedAt: string | null 29 } | null 30 hasSshKey: boolean 31 sshKey: { 32 publicKey: string 33 createdAt: string 34 rotatedAt: string | null 35 } | null 36 repos: DashboardRepo[] 37} 38 39export default defineEventHandler(async (event): Promise<DashboardPayload> => { 40 const session = await requireSession(event) 41 const db = useDb() 42 43 const [identityRow, installRows, repoRows, sshKeyRows] = await Promise.all([ 44 db.select({ did: userIdentity.did, handle: userIdentity.handle }) 45 .from(userIdentity) 46 .where(sql`${userIdentity.did} = ${session.did}`) 47 .limit(1), 48 db.select({ 49 id: installation.id, 50 accountLogin: installation.accountLogin, 51 accountType: installation.accountType, 52 suspendedAt: installation.suspendedAt, 53 }) 54 .from(installation) 55 .where(sql`${installation.id} = ${session.installationId}`) 56 .limit(1), 57 db.select().from(repoMapping) 58 .where(sql`${repoMapping.installationId} = ${session.installationId}`) 59 .orderBy(sql`${repoMapping.githubFullName}`), 60 db.select({ 61 publicKey: sshKey.publicKey, 62 createdAt: sshKey.createdAt, 63 rotatedAt: sshKey.rotatedAt, 64 }) 65 .from(sshKey) 66 .where(sql`${sshKey.installationId} = ${session.installationId} AND ${sshKey.did} = ${session.did}`) 67 .limit(1), 68 ]) 69 70 const installRow = installRows[0] ?? null 71 const sshKeyRow = sshKeyRows[0] ?? null 72 73 const repos: DashboardRepo[] = repoRows.map(row => { 74 // Schema audit prefers no new column for "last push time": `updatedAt` 75 // moves on any mapping mutation (status, errors, disable toggle), so it's 76 // a noisy proxy for "last sync". When at least one ref has synced, 77 // surface `updatedAt` as a best-effort timestamp; when refs is empty, we 78 // have nothing meaningful to show. 79 // eslint-disable-next-line ts/no-unsafe-type-assertion -- jsonb column is typed `unknown` 80 const refs = (row.lastSyncedRefs ?? {}) as Record<string, string> 81 const refKeys = Object.keys(refs) 82 return { 83 id: row.id, 84 githubRepoId: row.githubRepoId, 85 githubFullName: row.githubFullName, 86 tangledRepoDid: row.tangledRepoDid, 87 tangledFullName: row.tangledFullName, 88 knot: row.knot, 89 status: row.status, 90 lastError: row.lastError, 91 disabledAt: row.disabledAt?.toISOString() ?? null, 92 lastSyncedRefs: refs, 93 lastSyncedAt: refKeys.length > 0 && row.updatedAt ? row.updatedAt.toISOString() : null, 94 refCount: refKeys.length, 95 } 96 }) 97 98 const installationPayload: DashboardPayload['installation'] = installRow 99 ? { 100 id: installRow.id, 101 accountLogin: installRow.accountLogin, 102 accountType: installRow.accountType, 103 suspendedAt: installRow.suspendedAt?.toISOString() ?? null, 104 } 105 : null 106 107 const sshKeyPayload: DashboardPayload['sshKey'] = sshKeyRow 108 ? { 109 publicKey: sshKeyRow.publicKey, 110 createdAt: sshKeyRow.createdAt.toISOString(), 111 rotatedAt: sshKeyRow.rotatedAt?.toISOString() ?? null, 112 } 113 : null 114 115 return { 116 did: session.did, 117 handle: identityRow[0]?.handle ?? session.handle ?? null, 118 installation: installationPayload, 119 hasSshKey: sshKeyPayload !== null, 120 sshKey: sshKeyPayload, 121 repos, 122 } 123})