master
 1import { Octokit } from 'octokit'
 2import { Query, Variables } from 'megaera'
 3import { Commit } from './task/commits/commits.graphql.js'
 4import { PullRequest } from './task/pulls/pulls.graphql.js'
 5import { Issue } from './task/issues/issues.graphql.js'
 6import { retry } from '@octokit/plugin-retry'
 7import { throttling } from '@octokit/plugin-throttling'
 8import { log } from './log.js'
 9
10export { $, type TShellSync } from 'zurk'
11
12const MyOctokit = Octokit.plugin(retry, throttling)
13
14export function getOctokit(token: string) {
15  return new MyOctokit({
16    auth: token,
17    log,
18    throttle: {
19      onRateLimit: (retryAfter, options: any, octokit, retryCount) => {
20        octokit.log.warn(
21          `Request quota exhausted for request ${options.method} ${options.url}`,
22        )
23        if (retryCount <= 3) {
24          octokit.log.info(`Retrying after ${retryAfter} seconds!`)
25          return true
26        }
27      },
28      onSecondaryRateLimit: (retryAfter, options: any, octokit, retryCount) => {
29        octokit.log.warn(
30          `SecondaryRateLimit detected for request ${options.method} ${options.url}`,
31        )
32        if (retryCount <= 3) {
33          octokit.log.info(`Retrying after ${retryAfter} seconds!`)
34          return true
35        }
36      },
37    },
38    retry: { doNotRetry: ['429'] },
39  })
40}
41
42export function query<T extends Query>(
43  octokit: Octokit,
44  query: T,
45  variables: Variables<T>,
46) {
47  return octokit.graphql<ReturnType<T>>(query, variables)
48}
49
50export function paginate<T extends Query>(
51  octokit: Octokit,
52  query: T,
53  variables: Variables<T>,
54) {
55  return octokit.graphql.paginate.iterator<ReturnType<T>>(query, variables)
56}
57
58export function linkCommit(commit: Commit): string {
59  return `<a href="https://github.com/${commit.repository.owner.login}/${
60    commit.repository.name
61  }/commit/${commit.sha}">${commit.sha.slice(0, 7)}</a>`
62}
63
64export function linkPull(pull: PullRequest): string {
65  return `<a href="https://github.com/${pull.repository.owner.login}/${pull.repository.name}/pull/${pull.number}">#${pull.number}</a>`
66}
67
68export function linkIssue(issue: Issue): string {
69  return `<a href="https://github.com/${issue.repository.owner.login}/${issue.repository.name}/issues/${issue.number}">#${issue.number}</a>`
70}
71
72export function quoteAttr(s: string) {
73  return s
74    .replace(/&/g, '&amp;')
75    .replace(/'/g, '&apos;')
76    .replace(/"/g, '&quot;')
77    .replace(/</g, '&lt;')
78    .replace(/>/g, '&gt;')
79    .replace(/\r\n/g, '&#13;')
80    .replace(/[\r\n]/g, '&#13;')
81}
82
83export function parseMask(value: string): RegExp {
84  return new RegExp(`^${value}$`.replace('*', '.+'))
85}
86
87export function latest(a: Commit, b: Commit) {
88  return (
89    new Date(b.committedDate).getTime() - new Date(a.committedDate).getTime()
90  )
91}
92
93export function plural(count: number, singular: string, plural: string) {
94  return (count === 1 ? singular : plural).replace('%d', count.toString())
95}