11import type { AnyEntityIdentifierInput , EntityIdentifier } from '@gitkraken/provider-apis' ;
22import { EntityIdentifierProviderType , EntityType , EntityVersion } from '@gitkraken/provider-apis' ;
33import type { IntegrationId } from '../../../constants.integrations' ;
4- import { HostingIntegrationId , SelfHostedIntegrationId } from '../../../constants.integrations' ;
5- import type { IssueOrPullRequest } from '../../../git/models/issue' ;
4+ import { HostingIntegrationId , IssueIntegrationId , SelfHostedIntegrationId } from '../../../constants.integrations' ;
5+ import type { Container } from '../../../container' ;
6+ import type { Issue , IssueOrPullRequest } from '../../../git/models/issue' ;
7+ import type { PullRequest } from '../../../git/models/pullRequest' ;
68import { equalsIgnoreCase } from '../../../system/string' ;
79import type { LaunchpadItem } from '../../launchpad/launchpadProvider' ;
10+ import type { IssueResourceDescriptor , RepositoryDescriptor } from '../integration' ;
11+ import { isIssueResourceDescriptor , isRepositoryDescriptor } from '../integration' ;
12+ import type { GitConfigEntityIdentifier } from './models' ;
813
914function isGitHubDotCom ( domain : string ) : boolean {
1015 return equalsIgnoreCase ( domain , 'github.com' ) ;
@@ -18,6 +23,10 @@ function isLaunchpadItem(item: IssueOrPullRequest | LaunchpadItem): item is Laun
1823 return ( item as LaunchpadItem ) . uuid !== undefined ;
1924}
2025
26+ function isIssue ( item : IssueOrPullRequest | LaunchpadItem ) : item is Issue {
27+ return item . type === 'issue' ;
28+ }
29+
2130export function getEntityIdentifierInput ( entity : IssueOrPullRequest | LaunchpadItem ) : AnyEntityIdentifierInput {
2231 let entityType = EntityType . Issue ;
2332 if ( entity . type === 'pullrequest' ) {
@@ -34,13 +43,23 @@ export function getEntityIdentifierInput(entity: IssueOrPullRequest | LaunchpadI
3443 provider = EntityIdentifierProviderType . GitlabSelfHosted ;
3544 domain = entity . provider . domain ;
3645 }
46+ let projectId = null ;
47+ let resourceId = null ;
48+ if ( provider === EntityIdentifierProviderType . Jira ) {
49+ if ( ! isIssue ( entity ) || entity . project == null ) {
50+ throw new Error ( 'Jira issues must have a project' ) ;
51+ }
52+
53+ projectId = entity . project . id ;
54+ resourceId = entity . project . resourceId ;
55+ }
3756
3857 return {
3958 accountOrOrgId : null , // needed for Trello issues, once supported
4059 organizationName : null , // needed for Azure issues and PRs, once supported
41- projectId : null , // needed for Jira issues, Trello issues, and Azure issues and PRs, once supported
60+ projectId : projectId , // needed for Jira issues, Trello issues, and Azure issues and PRs, once supported
4261 repoId : null , // needed for Azure and BitBucket PRs, once supported
43- resourceId : null , // needed for Jira issues, once supported
62+ resourceId : resourceId , // needed for Jira issues
4463 provider : provider ,
4564 entityType : entityType ,
4665 version : EntityVersion . One ,
@@ -49,12 +68,16 @@ export function getEntityIdentifierInput(entity: IssueOrPullRequest | LaunchpadI
4968 } ;
5069}
5170
52- export function getProviderIdFromEntityIdentifier ( entityIdentifier : EntityIdentifier ) : IntegrationId | undefined {
71+ export function getProviderIdFromEntityIdentifier (
72+ entityIdentifier : EntityIdentifier | AnyEntityIdentifierInput ,
73+ ) : IntegrationId | undefined {
5374 switch ( entityIdentifier . provider ) {
5475 case EntityIdentifierProviderType . Github :
5576 return HostingIntegrationId . GitHub ;
5677 case EntityIdentifierProviderType . GithubEnterprise :
5778 return SelfHostedIntegrationId . GitHubEnterprise ;
79+ case EntityIdentifierProviderType . Jira :
80+ return IssueIntegrationId . Jira ;
5881 default :
5982 return undefined ;
6083 }
@@ -66,7 +89,107 @@ function fromStringToEntityIdentifierProviderType(str: string): EntityIdentifier
6689 return EntityIdentifierProviderType . Github ;
6790 case 'gitlab' :
6891 return EntityIdentifierProviderType . Gitlab ;
92+ case 'jira' :
93+ return EntityIdentifierProviderType . Jira ;
6994 default :
7095 throw new Error ( `Unknown provider type '${ str } '` ) ;
7196 }
7297}
98+
99+ export function encodeIssueOrPullRequestForGitConfig (
100+ entity : Issue | PullRequest ,
101+ resource : RepositoryDescriptor | IssueResourceDescriptor ,
102+ ) : GitConfigEntityIdentifier {
103+ const encodedResource : GitConfigEntityIdentifier [ 'resource' ] = {
104+ key : resource . key ,
105+ name : resource . name ,
106+ id : undefined ,
107+ owner : undefined ,
108+ } ;
109+ if ( isRepositoryDescriptor ( resource ) ) {
110+ encodedResource . owner = resource . owner ;
111+ } else if ( isIssueResourceDescriptor ( resource ) ) {
112+ encodedResource . id = resource . id ;
113+ } else {
114+ throw new Error ( 'Invalid resource' ) ;
115+ }
116+
117+ return {
118+ ...getEntityIdentifierInput ( entity ) ,
119+ searchId : entity . id ,
120+ resource : encodedResource ,
121+ createdDate : new Date ( ) . toISOString ( ) ,
122+ } ;
123+ }
124+
125+ export function isGitConfigEntityIdentifier ( entity : unknown ) : entity is GitConfigEntityIdentifier {
126+ return (
127+ entity != null &&
128+ typeof entity === 'object' &&
129+ 'provider' in entity &&
130+ entity . provider != null &&
131+ 'entityType' in entity &&
132+ entity . entityType != null &&
133+ 'version' in entity &&
134+ entity . version != null &&
135+ 'entityId' in entity &&
136+ entity . entityId != null &&
137+ 'searchId' in entity &&
138+ entity . searchId != null
139+ ) ;
140+ }
141+
142+ export function decodeEntityFromGitConfig ( str : string ) : GitConfigEntityIdentifier {
143+ const decoded = JSON . parse ( str ) ;
144+
145+ if ( ! isGitConfigEntityIdentifier ( decoded ) ) {
146+ throw new Error ( 'Invalid issue or pull request' ) ;
147+ }
148+
149+ if (
150+ decoded . provider === EntityIdentifierProviderType . Jira &&
151+ ( decoded . resourceId == null || decoded . projectId == null )
152+ ) {
153+ throw new Error ( 'Invalid Jira issue' ) ;
154+ }
155+
156+ return decoded ;
157+ }
158+
159+ export async function getIssueFromGitConfigEntityIdentifier (
160+ container : Container ,
161+ identifier : GitConfigEntityIdentifier ,
162+ ) : Promise < Issue | undefined > {
163+ if ( identifier . entityType !== EntityType . Issue ) {
164+ return undefined ;
165+ }
166+
167+ // TODO: Centralize where we represent all supported providers for issues
168+ if (
169+ identifier . provider !== EntityIdentifierProviderType . Jira &&
170+ identifier . provider !== EntityIdentifierProviderType . Github &&
171+ identifier . provider !== EntityIdentifierProviderType . Gitlab
172+ ) {
173+ return undefined ;
174+ }
175+
176+ const integrationId = getProviderIdFromEntityIdentifier ( identifier ) ;
177+ if ( integrationId == null ) {
178+ return undefined ;
179+ }
180+
181+ const integration = await container . integrations . get ( integrationId ) ;
182+ if ( integration == null ) {
183+ return undefined ;
184+ }
185+
186+ return integration . getIssue (
187+ {
188+ id : identifier . resource . id ,
189+ key : identifier . resource . key ,
190+ owner : identifier . resource . owner ,
191+ name : identifier . resource . name ,
192+ } ,
193+ identifier . searchId ,
194+ ) ;
195+ }
0 commit comments