MCPcopy Create free account
hub / github.com/47ng/nuqs / fetchPRNodes

Function fetchPRNodes

packages/scripts/lib/commit-graph.ts:298–361  ·  view source on GitHub ↗
(args: {
  prNumbers: number[]
  githubToken: string
  fnLabel: string
  selection: string
  nodeSchema: z.ZodType<T>
})

Source from the content-addressed store, hash-verified

296// finalize comments. We therefore fail loud when any error is present, and warn
297// on the (genuine) drops so they leave a trace.
298export async function fetchPRNodes<T extends { number: number }>(args: {
299 prNumbers: number[]
300 githubToken: string
301 fnLabel: string
302 selection: string
303 nodeSchema: z.ZodType<T>
304}): Promise<T[]> {
305 const { prNumbers, githubToken, fnLabel, selection, nodeSchema } = args
306 if (prNumbers.length === 0) return []
307 const aliases = prNumbers
308 .map(
309 number => `
310 pr${number}: pullRequest(number: ${number}) {
311 ${selection}
312 }`
313 )
314 .join('\n')
315 const query = `query { repository(owner: "47ng", name: "nuqs") { ${aliases} } }`
316
317 const response = await fetch(`https://api.github.com/graphql?fn=${fnLabel}`, {
318 method: 'POST',
319 headers: {
320 Authorization: `Bearer ${githubToken}`,
321 'Content-Type': 'application/json'
322 },
323 body: JSON.stringify({ query })
324 })
325 if (!response.ok) {
326 throw new Error(
327 `${fnLabel}: GitHub API error ${response.status} ${response.statusText} for PRs [${prNumbers.join(', ')}]`
328 )
329 }
330 const envelopeSchema = z.object({
331 data: z.object({
332 repository: z.record(z.string(), nodeSchema.nullable())
333 }),
334 errors: z.array(z.object({ message: z.string() })).optional()
335 })
336 const envelope = envelopeSchema.safeParse(await response.json())
337 if (!envelope.success) {
338 throw new Error(
339 `${fnLabel}: unexpected GraphQL response shape for PRs [${prNumbers.join(', ')}]: ${envelope.error.message}`
340 )
341 }
342 const { data, errors } = envelope.data
343 if (errors && errors.length > 0) {
344 // A null node here is a fetch failure, not a nonexistent PR — dropping it
345 // would silently lose a real change. Fail the release instead.
346 throw new Error(
347 `${fnLabel}: GraphQL errors for PRs [${prNumbers.join(', ')}]: ${errors.map(e => e.message).join('; ')}`
348 )
349 }
350 const resolved = Object.values(data.repository).filter(
351 (node): node is T => node !== null
352 )
353 if (resolved.length < prNumbers.length) {
354 const returned = new Set(resolved.map(node => node.number))
355 const dropped = prNumbers.filter(number => !returned.has(number))

Callers 3

fetchChangeDetailsFunction · 0.85
fetchClosingIssuesFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected