1 | |
2 |
|
3 | async function graphql(auth: RT.Github, query: string, variables: object) { |
4 | const response = await fetch("https://api.github.com/graphql", { |
5 | method: "POST", |
6 | headers: { |
7 | Authorization: `Bearer ${auth.token}`, |
8 | "Content-Type": "application/json", |
9 | Accept: "application/json", |
10 | }, |
11 | body: JSON.stringify({ query, variables }), |
12 | }) |
13 | if (!response.ok) { |
14 | throw new Error(`${response.status} ${await response.text()}`) |
15 | } |
16 | const { data, errors } = (await response.json()) as { |
17 | data: any |
18 | errors?: unknown[] |
19 | } |
20 | if (errors?.length) throw new Error(JSON.stringify(errors)) |
21 | return data |
22 | } |
23 |
|
24 | export type DynSelect_project_number = string |
25 |
|
26 | |
27 | export async function project_number(auth: RT.Github, owner: string) { |
28 | if (!auth?.token || !owner) return [] |
29 | const data = await graphql( |
30 | auth, |
31 | ` |
32 | query ($owner: String!) { |
33 | repositoryOwner(login: $owner) { |
34 | ... on ProjectV2Owner { |
35 | projectsV2(first: 100) { |
36 | nodes { |
37 | number |
38 | title |
39 | } |
40 | } |
41 | } |
42 | } |
43 | } |
44 | `, |
45 | { owner } |
46 | ) |
47 | return (data.repositoryOwner?.projectsV2?.nodes ?? []).map((p: any) => ({ |
48 | value: String(p.number), |
49 | label: `#${p.number} ${p.title}`, |
50 | })) |
51 | } |
52 |
|
53 | |
54 | * List Project Statuses |
55 | * List the options of a project's Status field (e.g. Todo, In Progress, Done) with their ids. Classic tokens and OAuth connections need the read:project scope. |
56 | */ |
57 | export async function main( |
58 | auth: RT.Github, |
59 | owner: string, |
60 | project_number: DynSelect_project_number |
61 | ) { |
62 | const data = await graphql( |
63 | auth, |
64 | ` |
65 | query ($owner: String!, $number: Int!) { |
66 | repositoryOwner(login: $owner) { |
67 | ... on ProjectV2Owner { |
68 | projectV2(number: $number) { |
69 | field(name: "Status") { |
70 | ... on ProjectV2SingleSelectField { |
71 | id |
72 | options { |
73 | id |
74 | name |
75 | color |
76 | description |
77 | } |
78 | } |
79 | } |
80 | } |
81 | } |
82 | } |
83 | } |
84 | `, |
85 | { owner, number: Number(project_number) } |
86 | ) |
87 | const field = data.repositoryOwner?.projectV2?.field |
88 | if (!field) throw new Error(`Project ${project_number} has no Status field`) |
89 | return field.options |
90 | } |
91 |
|