copykitku/src/vendor/github/repomgr.ts
2021-02-01 12:04:19 +01:00

195 lines
5.2 KiB
TypeScript

/*
* Copycat. Copyright (C) 2020 selfisekai <laura@selfisekai.rocks> and other contributors.
*
* This is free software, and you are welcome to redistribute it
* under the GNU General Public License 3.0 or later; see the LICENSE file for details,
* or, if the file is unavailable, visit <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*/
import {
RepoManager,
Issue,
Repo,
ACTOR_TYPE,
ISSUE_STATE,
MergeRequest,
MERGE_REQUEST_STATE,
MERGE_REQUEST_MERGABILITY,
ENTITY_TYPE,
} from '../../types';
import GitHubVendorManager from './vendormgr';
import assert from 'assert';
import { GHMutation, GHMutationCreateIssueArgs } from './api-types';
export default class GitHubRepoManager implements RepoManager {
vendorMgr: GitHubVendorManager;
repo: Repo;
repoId: string;
constructor(vendorMgr: GitHubVendorManager, repoPath: string) {
this.vendorMgr = vendorMgr;
const mobj = /^([^/\s]+)\/([^/\s]+)$/.exec(repoPath);
assert(mobj, 'invalid repo path');
const [, owner, repoName] = mobj;
this.repo = {
vendor: this.vendorMgr.vendor,
owner: {
type: ACTOR_TYPE.UNKNOWN,
username: owner,
vendor: this.vendorMgr.vendor,
},
name: repoName,
};
this.repoId = '';
}
public async initialize() {
const meta = await this.vendorMgr._doRequest(
`
query Query($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
id
name
owner {
login
__typename
}
}
}
`,
{
owner: this.repo.owner.username,
name: this.repo.name,
},
);
assert(meta.repository);
assert(meta.repository.owner);
this.repoId = meta.repository.id;
this.repo.name = meta.repository.name;
this.repo.owner.username = meta.repository.owner.login;
// @ts-ignore graphql-codegen ignores built-in graphql values
switch (meta.repository.owner.__typename) {
case 'Organization':
this.repo.owner.type = ACTOR_TYPE.ORG;
break;
case 'User':
this.repo.owner.type = ACTOR_TYPE.USER;
break;
}
return this;
}
public async getIssue(number: string): Promise<Issue> {
const resp = await this.vendorMgr._doRequest(
`
query Query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
issue(number: $number) {
title
body
closed
}
}
}
`,
{
owner: this.repo.owner.username,
name: this.repo.name,
number: parseInt(number, 10),
},
);
assert(resp.repository, 'no repository');
assert(resp.repository.issue, 'no issue');
const { issue } = resp.repository;
return {
type: ENTITY_TYPE.ISSUE,
id: number,
content: issue.body,
title: issue.title,
repo: this.repo,
state: issue.closed ? ISSUE_STATE.CLOSED : ISSUE_STATE.OPEN,
};
}
public async replicateIssue(issue: Issue) {
const resp = await this.vendorMgr._doRequest<GHMutation, GHMutationCreateIssueArgs>(
`
mutation ($input: CreateIssueInput!) {
createIssue(input: $input) {
issue {
number
title
body
closed
}
}
}
`,
{
input: {
repositoryId: this.repoId,
title: issue.title,
body: issue.content,
},
},
);
assert(resp.createIssue, 'creating issue failed');
assert(resp.createIssue.issue, 'creating issue failed');
const replicated = resp.createIssue.issue;
return {
type: ENTITY_TYPE.ISSUE,
id: replicated.number.toString(),
content: replicated.body,
title: replicated.title,
repo: this.repo,
state: replicated.closed ? ISSUE_STATE.CLOSED : ISSUE_STATE.OPEN,
};
}
public async getMergeRequest(number: string): Promise<MergeRequest> {
const resp = await this.vendorMgr._doRequest(
`
query Query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
title
body
isDraft
mergeable
state
}
}
}
`,
{
owner: this.repo.owner.username,
name: this.repo.name,
number: parseInt(number, 10),
},
);
assert(resp.repository, 'no repository');
assert(resp.repository.pullRequest, 'no pull request');
const { pullRequest } = resp.repository;
return {
type: ENTITY_TYPE.MERGE_REQUEST,
id: number,
content: pullRequest.body,
title: pullRequest.title,
repo: this.repo,
state: {
OPEN: MERGE_REQUEST_STATE.OPEN,
CLOSED: MERGE_REQUEST_STATE.CLOSED,
MERGED: MERGE_REQUEST_STATE.MERGED,
}[pullRequest.state],
mergability: {
MERGEABLE: MERGE_REQUEST_MERGABILITY.MERGEABLE,
CONFLICTING: MERGE_REQUEST_MERGABILITY.CONFLICTING,
UNKNOWN: null,
}[pullRequest.mergeable],
isDraft: pullRequest.isDraft,
};
}
}