Skip to content
← Public packages

@kody/github

Call GitHub REST, GraphQL, and pull requests with a GitHub OAuth App or a personal access token.

src/types.ts

133 lines · 3.4 KB · TypeScript
export type GitHubAuthMode = "oauth" | "pat"

export type GitHubQueryValue = string | number | boolean | null | undefined

export type GitHubQuery = Record<string, GitHubQueryValue>

export type GitHubHeaders = Record<string, string>

export interface GitHubAuthInput {
  /**
   * Saved OAuth integration name. Defaults to `github` when `secretName` is
   * omitted. Pass a distinct name (`github-work`, `github-bot`, …) for each
   * additional connected GitHub identity.
   */
  integrationName?: string
  /**
   * Personal access token secret name. When set, the PAT lane is used and
   * `integrationName` is ignored. The documented default PAT name is
   * `githubAccessToken`.
   */
  secretName?: string
  /**
   * Alias for `integrationName`. Use `github` or `github-<purpose>`.
   * The retired alias `bot` throws with setup URLs.
   */
  account?: string
}

export interface GitHubResolvedAuth {
  mode: GitHubAuthMode
  integrationName: string | null
  secretName: string | null
  label: string
}

export interface GitHubAuthLaneInfo {
  lane: GitHubAuthMode
  default: boolean
  integrationName?: string
  secretName?: string
  connectUrl?: string
  secretSetupUrl?: string
  useWhen: string
  avoidWhen: string
  mutationGuidance: string
}

export interface GitHubRequestOptions extends GitHubAuthInput {
  path: string
  method?: string
  query?: GitHubQuery
  headers?: GitHubHeaders
  body?: unknown
  throwOnError?: boolean
  /**
   * When true, mutating requests return a preview and do not call GitHub.
   * Safe methods (`GET`, `HEAD`, `OPTIONS`) still execute so smoke tests work.
   */
  dryRun?: boolean
  /**
   * Required for live mutating REST calls (`POST`, `PUT`, `PATCH`, `DELETE`).
   * Omit when `dryRun` is true.
   */
  confirm?: boolean
}

export interface GitHubResponse<TData = unknown> {
  auth: GitHubResolvedAuth
  url: string
  ok: boolean
  status: number
  statusText: string
  headers: GitHubHeaders
  data: TData | null
  text: string
  dryRun?: boolean
}

export interface GitHubGraphqlOptions<TVariables extends Record<string, unknown> = Record<string, unknown>>
  extends GitHubAuthInput {
  query: string
  variables?: TVariables
  headers?: GitHubHeaders
  throwOnError?: boolean
  dryRun?: boolean
  confirm?: boolean
}

export interface GitHubGraphqlError {
  message: string
  path?: Array<string | number>
  type?: string
  locations?: Array<{ line: number; column: number }>
  extensions?: Record<string, unknown>
}

export interface GitHubGraphqlResponse<TData = unknown> extends Omit<GitHubResponse<unknown>, "data"> {
  data: TData | null
  errors?: GitHubGraphqlError[]
}

export interface GitHubPaginateOptions extends Omit<GitHubRequestOptions, "body" | "throwOnError" | "dryRun" | "confirm"> {
  maxPages?: number
}

export interface GitHubPaginationResult<TItem = unknown> {
  auth: GitHubResolvedAuth
  items: TItem[]
  pages: number
  lastResponse: GitHubResponse<unknown> | null
}

export interface GitHubViewer {
  auth: GitHubResolvedAuth
  login: string
  id: number
  type: string
  name: string | null
  email: string | null
  htmlUrl: string
}

/**
 * Describes the shared type exports for the GitHub package.
 */
export default function describeGithubTypes() {
  return {
    auth: "integrationName (OAuth, default github) or secretName (PAT)",
    request: "GitHubRequestOptions -> GitHubResponse<TData>",
    graphql: "GitHubGraphqlOptions -> GitHubGraphqlResponse<TData>",
    paginate: "GitHubPaginateOptions -> GitHubPaginationResult<TItem>",
  }
}