|
1 | 1 | <script lang="ts">
|
| 2 | + import { dev } from "$app/environment"; |
| 3 | + import { env } from "$env/dynamic/public"; |
2 | 4 | import type { Issues, LinkedEntity, Pulls } from "./types";
|
3 | 5 | import PageRenderer from "./PageRenderer.svelte";
|
4 | 6 | import LoaderCircle from "lucide-svelte/icons/loader-circle";
|
5 | 7 |
|
6 | 8 | export let data;
|
7 | 9 |
|
| 10 | + async function linkedIssuesForPR( |
| 11 | + owner: string, |
| 12 | + repo: string, |
| 13 | + pr: number |
| 14 | + ): Promise<LinkedEntity[]> { |
| 15 | + return data.octokit |
| 16 | + .graphql( |
| 17 | + ` |
| 18 | + query closingIssues($number: Int!, $owner: String!, $repo: String!) { |
| 19 | + repository(owner: $owner, name: $repo) { |
| 20 | + pullRequest(number: $number) { |
| 21 | + closingIssuesReferences(first: 10) { |
| 22 | + nodes { |
| 23 | + createdAt |
| 24 | + author { |
| 25 | + login |
| 26 | + avatarUrl |
| 27 | + } |
| 28 | + number |
| 29 | + title |
| 30 | + body |
| 31 | + } |
| 32 | + } |
| 33 | + } |
| 34 | + } |
| 35 | + } |
| 36 | + `, |
| 37 | + { |
| 38 | + owner, |
| 39 | + repo, |
| 40 | + number: pr |
| 41 | + } |
| 42 | + ) |
| 43 | + .then( |
| 44 | + /* eslint-disable @typescript-eslint/no-explicit-any */ (response: any) => |
| 45 | + response.repository.pullRequest.closingIssuesReferences.nodes |
| 46 | + ) |
| 47 | + .catch(() => []); |
| 48 | + } |
| 49 | +
|
8 | 50 | // PR issues or issue PRs
|
9 | 51 | let linkedPRsOrIssues: LinkedEntity[] | undefined = undefined;
|
10 | 52 |
|
|
78 | 120 | .then(({ data }) => (prInfo.files = data));
|
79 | 121 |
|
80 | 122 | // Fetch closing issues
|
81 |
| - data.octokit |
82 |
| - .graphql( |
83 |
| - ` |
84 |
| - query closingIssues($number: Int!, $owner: String!, $repo: String!) { |
85 |
| - repository(owner: $owner, name: $repo) { |
86 |
| - pullRequest(number: $number) { |
87 |
| - closingIssuesReferences(first: 10) { |
88 |
| - nodes { |
89 |
| - createdAt |
90 |
| - author { |
91 |
| - login |
92 |
| - avatarUrl |
93 |
| - } |
94 |
| - number |
95 |
| - title |
96 |
| - body |
97 |
| - } |
98 |
| - } |
99 |
| - } |
100 |
| - } |
101 |
| - } |
102 |
| - `, |
103 |
| - { |
104 |
| - owner: data.org, |
105 |
| - repo: data.repo, |
106 |
| - number: data.id |
107 |
| - } |
108 |
| - ) |
109 |
| - .then( |
110 |
| - /* eslint-disable @typescript-eslint/no-explicit-any */ (response: any) => { |
111 |
| - linkedPRsOrIssues = response.repository.pullRequest.closingIssuesReferences.nodes; |
112 |
| - } |
113 |
| - ) |
114 |
| - .catch(() => (linkedPRsOrIssues = [])); |
| 123 | + linkedIssuesForPR(data.org, data.repo, data.id).then(response => { |
| 124 | + linkedPRsOrIssues = response; |
| 125 | + }); |
115 | 126 | }
|
116 | 127 | $: if (pullOrIssue === "issues") {
|
117 | 128 | linkedPRsOrIssues = [];
|
|
147 | 158 | repo: data.repo,
|
148 | 159 | issue_number: data.id
|
149 | 160 | })
|
150 |
| - .then(({ data: response }) => { |
151 |
| - prsToFetch = response |
152 |
| - .filter(event => event.event === "cross-referenced") |
153 |
| - .map(event => { |
154 |
| - const anyEvent = event as any; // doesn't have the source property for some reason |
155 |
| - return anyEvent.source.issue.number; |
156 |
| - }); |
| 161 | + .then(({ data: events }) => |
| 162 | + events.filter( |
| 163 | + event => |
| 164 | + event.event === "cross-referenced" && |
| 165 | + "source" in event && |
| 166 | + event.source.issue?.repository?.owner.login === data.org && |
| 167 | + event.source.issue?.repository?.name === data.repo |
| 168 | + ) |
| 169 | + ) |
| 170 | + .then(async crEvents => { |
| 171 | + const prEvents = []; |
| 172 | + for (let event of crEvents) { |
| 173 | + const anyEvent = event as any; |
| 174 | + const response = await fetch( |
| 175 | + `https://api.github.com/repos/${data.org}/${data.repo}/pulls/${anyEvent.source.issue.number}`, |
| 176 | + { |
| 177 | + headers: |
| 178 | + dev && env.PUBLIC_GITHUB_TOKEN |
| 179 | + ? { |
| 180 | + Authorization: `token ${env.PUBLIC_GITHUB_TOKEN}` |
| 181 | + } |
| 182 | + : undefined |
| 183 | + } |
| 184 | + ); |
| 185 | + if (response.ok) { |
| 186 | + const containedInPr = await linkedIssuesForPR( |
| 187 | + data.org, |
| 188 | + data.repo, |
| 189 | + anyEvent.source.issue.number |
| 190 | + ); |
| 191 | + if (containedInPr.map(pr => pr.number).includes(data.id)) { |
| 192 | + prEvents.push(event); |
| 193 | + } |
| 194 | + } |
| 195 | + } |
| 196 | + return prEvents; |
| 197 | + }) |
| 198 | + .then(prEvents => { |
| 199 | + prsToFetch = prEvents.map(event => (event as any).source.issue.number); |
157 | 200 | })
|
158 | 201 | .catch(() => (linkedPRsOrIssues = []));
|
159 | 202 | }
|
|
193 | 236 | prNumber => !prs.map(pr => pr.data.number).includes(prNumber)
|
194 | 237 | );
|
195 | 238 | })
|
196 |
| - .catch(() => (linkedPRsOrIssues = [])); |
| 239 | + .catch(() => (prsToFetch = [])); |
197 | 240 | }
|
198 | 241 | </script>
|
199 | 242 |
|
|
0 commit comments