Skip to content

Commit 7c7e9a1

Browse files
committed
adds /v1/github/users|orgs/{login_name}/projects/{project_id_or_name}/repositories/collaborators (closes #55)
1 parent e84f188 commit 7c7e9a1

File tree

3 files changed

+128
-37
lines changed

3 files changed

+128
-37
lines changed

src/v1/adapters/github/index.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,55 @@ const ACCOUNT_LEVEL_CHILDREN = (login_type: "organization" | "user") =>
969969
tags: ["github"],
970970
},
971971
},
972+
)
973+
.get(
974+
"/collaborators",
975+
async ({
976+
fetchParams,
977+
params: { login_name, project_id_or_name },
978+
query,
979+
set,
980+
}) => {
981+
const response =
982+
await fetchGithubDataUsingGraphql<{
983+
project: ProjectV2;
984+
}>(
985+
AccountScopeEntryRoot(
986+
login_name,
987+
getAllRepositoriesInProject(
988+
project_id_or_name,
989+
[
990+
GITHUB_PROJECT_SCOPES.REPOSITORIES_LINKED,
991+
],
992+
[
993+
{
994+
scopeName: "collaborators",
995+
pageSize: query.pageSize ?? 1,
996+
continueAfter: query.continueAfter,
997+
},
998+
{
999+
scopeName: "count",
1000+
pageSize: query.rootPageSize ?? 1,
1001+
continueAfter:
1002+
query.rootContinueAfter,
1003+
},
1004+
] as PageSize<GITHUB_REPOSITORY_SCOPES>[],
1005+
),
1006+
login_type,
1007+
),
1008+
fetchParams.auth,
1009+
set,
1010+
fetchParams.auth_type,
1011+
);
1012+
1013+
return response;
1014+
},
1015+
{
1016+
detail: {
1017+
description: `Request repository collaborators in the ${login_type} project. (Your token has to have push permission in the repositories.)`,
1018+
tags: ["github"],
1019+
},
1020+
},
9721021
),
9731022
)
9741023

@@ -1167,7 +1216,7 @@ const ACCOUNT_LEVEL_CHILDREN = (login_type: "organization" | "user") =>
11671216
[
11681217
{
11691218
scopeName: "milestones", // fetches a single milestone, because amount is set to singular
1170-
pageSize: null ?? 1,
1219+
pageSize: 1,
11711220
continueAfter: null,
11721221
},
11731222
{

src/v1/adapters/github/scopes.ts

Lines changed: 76 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { Fetcher, FetcherExtended } from "../scopes";
1111
// JS doesn't allow inheriting private (_<property/function>) properties and functions and protected ones (_<property/function>) have getters and setters per default, because they are just a convention and have to be implemented by the programmer :).
1212
// It is not possible to make private properties inheritable in JavaScript, as the private properties of a class are not inherited by its subclasses. This is because private properties are not part of the class's public interface, and they are not accessible from outside the class.
1313
// They are private, because only the fetching functions should be visible for code completion and because ít feels illegal to expose them, because they should only be set and used within the class.
14-
// biome-ignore lint/complexity/noStaticOnlyClass: Prettier like that, who needs speed, am I right?
1514
abstract class AccountFetcher extends Fetcher {
1615
static packages(
1716
packagePageSize: number,
@@ -371,31 +370,7 @@ export class UserFetcher extends FetcherExtended {
371370
if (this.#doFetchInfo) {
372371
if (this.#log) console.info("fetching info");
373372

374-
return `
375-
bio
376-
websiteUrl
377-
createdAt
378-
379-
status {
380-
message
381-
emoji
382-
indicatesLimitedAvailability
383-
}
384-
socialAccounts(first: 10) {
385-
${this.#count_nodes ? "totalCount" : ""}
386-
387-
pageInfo {
388-
endCursor
389-
hasNextPage
390-
}
391-
392-
nodes {
393-
provider
394-
displayName
395-
url
396-
}
397-
}
398-
`;
373+
return UserBodyInfo(this.#count_nodes);
399374
}
400375

401376
return "";
@@ -405,21 +380,53 @@ export class UserFetcher extends FetcherExtended {
405380
if (this.#doFetchEssential) {
406381
if (this.#log) console.info("fetching essential");
407382

408-
return `
409-
name
410-
pronouns
411-
location
412-
avatarUrl
413-
url
414-
company
415-
email
416-
`;
383+
return UserBodyEssential();
417384
}
418385

419386
return "";
420387
}
421388
}
422389

390+
function UserBodyEssential() {
391+
return `
392+
name
393+
pronouns
394+
location
395+
avatarUrl
396+
url
397+
company
398+
email
399+
`;
400+
}
401+
402+
function UserBodyInfo(count_nodes = false) {
403+
return `
404+
bio
405+
websiteUrl
406+
createdAt
407+
408+
status {
409+
message
410+
emoji
411+
indicatesLimitedAvailability
412+
}
413+
socialAccounts(first: 10) {
414+
${count_nodes ? "totalCount" : ""}
415+
416+
pageInfo {
417+
endCursor
418+
hasNextPage
419+
}
420+
421+
nodes {
422+
provider
423+
displayName
424+
url
425+
}
426+
}
427+
`;
428+
}
429+
423430
export class Repository extends FetcherExtended {
424431
#doFetchEssential = true;
425432
#doFetchInfo = false;
@@ -432,6 +439,7 @@ export class Repository extends FetcherExtended {
432439
#doFetchLanguages = false;
433440
#doFetchMilestones = false;
434441
#doFetchIssues = false;
442+
#doFetchCollaborators = false;
435443

436444
static defaultPageSize = 10;
437445
#rootPageSize: number;
@@ -443,6 +451,7 @@ export class Repository extends FetcherExtended {
443451
#languagesPageSize: number;
444452
#milestonesPageSize: number;
445453
#issuesPageSize: number;
454+
#collaboratorsPageSize: number;
446455

447456
#rootContinueAfter: string | undefined | null = null;
448457
#vulnerabilitiesContinueAfter: string | undefined | null = null;
@@ -453,6 +462,7 @@ export class Repository extends FetcherExtended {
453462
#languagesContinueAfter: string | undefined | null = null;
454463
#milestonesContinueAfter: string | undefined | null = null;
455464
#issuesContinueAfter: string | undefined | null = null;
465+
#collaboratorsContinueAfter: string | undefined | null = null;
456466

457467
#count_nodes = false;
458468
#log = false;
@@ -475,6 +485,7 @@ export class Repository extends FetcherExtended {
475485
this.#languagesPageSize = Repository.defaultPageSize;
476486
this.#milestonesPageSize = Repository.defaultPageSize;
477487
this.#issuesPageSize = Repository.defaultPageSize;
488+
this.#collaboratorsPageSize = Repository.defaultPageSize;
478489

479490
this.#parseScopes(args.scopes);
480491
}
@@ -551,6 +562,11 @@ export class Repository extends FetcherExtended {
551562
this.#rootPageSize = ps.pageSize ?? this.#rootPageSize;
552563
this.#rootContinueAfter = this.#validateCursor(ps.continueAfter);
553564
break;
565+
case GITHUB_REPOSITORY_SCOPES.COLLABORATORS:
566+
this.#doFetchCollaborators = true;
567+
this.#collaboratorsPageSize = ps.pageSize ?? this.#collaboratorsPageSize;
568+
this.#collaboratorsContinueAfter = this.#validateCursor(ps.continueAfter);
569+
break;
554570
default:
555571
break;
556572
}
@@ -609,6 +625,7 @@ export class Repository extends FetcherExtended {
609625
${this.#releasesBody()}
610626
${this.#deploymentsBody()}
611627
${this.#languagesBody()}
628+
${this.#collaboratorsBody()}
612629
}
613630
`;
614631
}
@@ -634,6 +651,7 @@ export class Repository extends FetcherExtended {
634651
${this.#releasesBody()}
635652
${this.#deploymentsBody()}
636653
${this.#languagesBody()}
654+
${this.#collaboratorsBody()}
637655
}
638656
}`;
639657
}
@@ -1176,4 +1194,27 @@ export class Repository extends FetcherExtended {
11761194

11771195
return "";
11781196
}
1197+
1198+
#collaboratorsBody() {
1199+
if (this.#doFetchCollaborators) {
1200+
if (this.#log) console.info("fetching collaborators");
1201+
1202+
return `
1203+
collaborators(affiliation: ALL, first: ${this.#collaboratorsPageSize}, after: ${this.#collaboratorsContinueAfter}) {
1204+
${this.#count_nodes ? "totalCount" : ""}
1205+
1206+
pageInfo {
1207+
endCursor
1208+
hasNextPage
1209+
}
1210+
1211+
nodes {
1212+
${UserBodyEssential()}
1213+
}
1214+
}
1215+
`;
1216+
}
1217+
1218+
return "";
1219+
}
11791220
}

src/v1/adapters/github/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export interface RestResponse<T> {
3636
type?: string | undefined;
3737
}
3838

39-
export interface GraphqlResponse<T> extends RestResponse<T> {}
39+
export interface GraphqlResponse<T> extends RestResponse<T> { }
4040

4141
// in type GraphQlQueryResponse<ResponseData> of @octokit/graphql (has string as type...)
4242
export enum GraphqlResponseErrorCode {
@@ -88,6 +88,7 @@ export enum GITHUB_REPOSITORY_SCOPES {
8888
LANGUAGES = "languages",
8989
MILESTONES = "milestones",
9090
ISSUES = "issues",
91+
COLLABORATORS = "collaborators",
9192
}
9293

9394
export enum GITHUB_MILESTONE_ISSUE_STATES {

0 commit comments

Comments
 (0)