1- import type { TimelineEvents } from "@acme/extract-schema" ;
1+ import type { Member , NewMember , TimelineEvents } from "@acme/extract-schema" ;
22import type { Entities , ExtractFunction } from "./config"
33import type { SourceControl } from "@acme/source-control" ;
44import { eq , sql } from "drizzle-orm" ;
@@ -11,10 +11,11 @@ export type GetTimelineEventsInputs = {
1111
1212export type GetTimelineEventsOutput = {
1313 timelineEvents : TimelineEvents [ ] ;
14+ members : Member [ ] ;
1415} ;
1516
1617export type GetTimelineEventsSourceControl = Pick < SourceControl , "fetchTimelineEvents" > ;
17- export type GetTimelineEventsEntities = Pick < Entities , "namespaces" | "repositories" | "mergeRequests" | "timelineEvents" > ;
18+ export type GetTimelineEventsEntities = Pick < Entities , "namespaces" | "repositories" | "mergeRequests" | "timelineEvents" | "members" | "repositoriesToMembers" > ;
1819
1920export type GetTimelineEventsFunction = ExtractFunction < GetTimelineEventsInputs , GetTimelineEventsOutput , GetTimelineEventsSourceControl , GetTimelineEventsEntities >
2021
@@ -37,6 +38,42 @@ export const getTimelineEvents: GetTimelineEventsFunction = async (
3738
3839 const { timelineEvents } = await integrations . sourceControl . fetchTimelineEvents ( repository , namespace , mergeRequest ) ;
3940
41+ const nonCommitEvents = timelineEvents . filter ( ev => ev . type !== "committed" ) ;
42+
43+ const uniqueTimelineActors = [ ...nonCommitEvents . reduce ( ( externalIdToActor , event ) =>
44+ event . actorId ? externalIdToActor . set ( event . actorId , { // actorId is optional due to commit events
45+ externalId : event . actorId ,
46+ username : event . actorName ,
47+ forgeType : repository . forgeType ,
48+ extractedSource : 'timeline' ,
49+ } ) : externalIdToActor , new Map < number , NewMember > ( ) ) . values ( ) ] ;
50+
51+
52+ const insertedUniqueTimelineActors = uniqueTimelineActors . length === 0 ? [ ] : await db . transaction ( async ( tx ) => {
53+ return Promise . all ( uniqueTimelineActors . map ( actor =>
54+ tx . insert ( entities . members ) . values ( actor )
55+ . onConflictDoUpdate ( {
56+ target : [
57+ entities . members . externalId ,
58+ entities . members . forgeType
59+ ] ,
60+ set : {
61+ username : actor . username ,
62+ _updatedAt : sql `(strftime('%s', 'now'))` ,
63+ } ,
64+ } )
65+ . returning ( )
66+ . get ( )
67+ ) ) ;
68+ } ) ;
69+
70+ if ( insertedUniqueTimelineActors . length > 0 ) {
71+ await db . insert ( entities . repositoriesToMembers )
72+ . values ( insertedUniqueTimelineActors . map ( member => ( { memberId : member . id , repositoryId } ) ) )
73+ . onConflictDoNothing ( )
74+ . run ( ) ;
75+ }
76+
4077 const insertedTimelineEvents = await db . transaction ( async ( tx ) => {
4178 return Promise . all ( timelineEvents . map ( event =>
4279 tx . insert ( entities . timelineEvents ) . values ( event )
@@ -54,5 +91,6 @@ export const getTimelineEvents: GetTimelineEventsFunction = async (
5491
5592 return {
5693 timelineEvents : insertedTimelineEvents ,
94+ members : insertedUniqueTimelineActors
5795 } ;
5896}
0 commit comments