import { Repo , Issue , PullRequest , Comment } from '../../DataTypes' ; import { HostingConfigBase } from '../HostingConfigBase' ; import { HostingClientBase } from '../HostingClientBase' ; import { PullRequestEvent , LabelUpdateEvent , CommentUpdateEvent , IssueEvent , } from '../../../plugin/event-manager/events' ; import { HostingClientRepoDataInitedEvent } from '../event' ; import { ClientServiceBase } from './ClientServiceBase' ; import { Application } from 'egg' ; import { waitUntil , ParseDate } from '../../Utils' ; export class RepoDataService < TConfig extends HostingConfigBase , TRawClient > extends ClientServiceBase < TConfig , TRawClient > { private repoData : Repo ; constructor ( app , client ) { super ( app , client , 'repoDataService' ) ; } public async onStart ( ) { this . client . eventService . subscribeAll ( PullRequestEvent , async ( e ) => { if ( e . pullRequest ) this . updatePull ( e . action , e . pullRequest ) ; } ) ; this . client . eventService . subscribeAll ( LabelUpdateEvent , async ( e ) => { if ( e . labelName ) this . updateLabel ( e . action , e . labelName , e . from ) ; } ) ; this . client . eventService . subscribeAll ( CommentUpdateEvent , async ( e ) => { if ( ! e . comment ) return ; if ( e . isIssue === true ) { this . updateIssueComment ( e . action , e . issueNumber , e . comment ) ; } else { this . updatePullComment ( e . action , e . issueNumber , e . comment ) ; } } ) ; this . client . eventService . subscribeAll ( IssueEvent , async ( e ) => { if ( e . issue ) this . updateIssue ( e . action , e . issue ) ; } ) ; this . client . eventService . subscribeAll ( HostingClientRepoDataInitedEvent , async ( e ) => { this . logger . info ( 'Repo data inited, update local data.' ) ; this . repoData = e . repoData ; this . formatRepoData ( ) ; } ) ; } public async onDispose ( ) { } public async onConfigLoaded ( ) { } public async syncData ( ) { this . logger . info ( 'Start to sync repo data' ) ; await waitUntil ( ( ) => this . repoData !== undefined ) ; this . client . eventService . publish ( 'all' , HostingClientRepoDataInitedEvent , { installationId : this . client . getHostId ( ) , fullName : this . client . getFullName ( ) , repoData : this . repoData , } ) ; } public getRepoData ( ) { return this . repoData ; } public setRepoData ( repoData ) { this . repoData = repoData ; } public updateLabel ( action , label , from ? ) { if ( ! this . repoData ) return ; this . repoData . issues . forEach ( v => { if ( action === 'deleted' ) { const index = v . labels . findIndex ( l => l === label ) ; if ( index === - 1 ) return ; v . labels . splice ( index , 1 ) ; } else if ( action === 'edited' ) { const index = v . labels . findIndex ( l => l === from ) ; if ( index === - 1 ) return ; v . labels [ index ] = label ; } } ) ; this . repoData . pulls . forEach ( v => { if ( action === 'deleted' ) { const index = v . labels . findIndex ( l => l === label ) ; if ( index !== - 1 ) v . labels . splice ( index , 1 ) ; } else if ( action === 'edited' ) { const index = v . labels . findIndex ( l => l === from ) ; if ( index !== - 1 ) v . labels [ index ] = label ; } } ) ; } public updateIssue ( action , issue ) { if ( ! this . repoData ) return ; if ( action === 'opened' ) { this . repoData . issues . push ( issue ) ; } else { const index = this . repoData . issues . findIndex ( v => v . id === issue . id ) ; if ( index !== - 1 ) { issue . comments = this . repoData . issues [ index ] . comments ; this . repoData . issues [ index ] = issue ; } } } public updatePull ( action , pull ) { if ( ! this . repoData ) return ; if ( action === 'opened' ) { this . repoData . pulls . push ( pull ) ; } else { const index = this . repoData . pulls . findIndex ( v => v . id === pull . id ) ; if ( index !== - 1 ) { pull . comments = this . repoData . pulls [ index ] . comments ; this . repoData . pulls [ index ] = pull ; } } } public updateIssueComment ( action , issueNumber , comment ) { if ( ! this . repoData ) return ; const issue = this . repoData . issues . find ( v => v . number === issueNumber ) ; if ( ! issue ) return ; if ( action === 'created' ) { issue . comments . push ( comment ) ; } else { const index = issue . comments . findIndex ( v => v . id === comment . id ) ; if ( index === - 1 ) return ; if ( action === 'deleted' ) { issue . comments . splice ( index , 1 ) ; } else { issue . comments [ index ] = comment ; } } } public updatePullComment ( action , pullNumber , comment ) { if ( ! this . repoData ) return ; const pull = this . repoData . pulls . find ( v => v . number === pullNumber ) ; if ( ! pull ) return ; if ( action === 'created' ) { pull . comments . push ( comment ) ; } else { const index = pull . comments . findIndex ( v => v . id === comment . id ) ; if ( index === - 1 ) return ; if ( action === 'deleted' ) { pull . comments . splice ( index , 1 ) ; } else { pull . comments [ index ] = comment ; } } } private formatRepoData ( ) { this . repoData . ownerInfo . createdAt = ParseDate ( this . repoData . ownerInfo . createdAt as any ) ; this . repoData . createdAt = ParseDate ( this . repoData . createdAt as any ) as any ; this . repoData . updatedAt = ParseDate ( this . repoData . updatedAt as any ) ; this . repoData . pushedAt = ParseDate ( this . repoData . pushedAt as any ) ; this . repoData . issues . forEach ( issue => { issue . closedAt = ParseDate ( issue . closedAt as any ) ; issue . createdAt = ParseDate ( issue . createdAt as any ) as any ; issue . updatedAt = ParseDate ( issue . updatedAt as any ) ; issue . comments . forEach ( c => c . createdAt = ParseDate ( c . createdAt as any ) as any ) ; } ) ; this . repoData . pulls . forEach ( pull => { pull . createdAt = ParseDate ( pull . createdAt as any ) as any ; pull . updatedAt = ParseDate ( pull . updatedAt as any ) as any ; pull . closedAt = ParseDate ( pull . closedAt as any ) ; pull . mergedAt = ParseDate ( pull . mergedAt as any ) ; pull . comments . forEach ( c => c . createdAt = ParseDate ( c . createdAt as any ) as any ) ; pull . reviewComments . forEach ( rc => rc . createdAt = ParseDate ( rc . createdAt as any ) as any ) ; } ) ; } }