UNPKG

@discublog/api

Version:

A ready-to-use, reusable wrapper for the GitHub Discussions API, based on the GitHub GraphQL API.

249 lines (248 loc) 6.5 kB
import { Octokit } from '@octokit/core'; function check(config) { if (!config.client || !config.owner || !config.name) { throw new Error(`Please call auth() first to configure the client`); } return config; } export function auth(config, params) { config.client = new Octokit({ auth: params.token }); config.owner = params.owner; config.name = params.name; } // Discussion Categories export function queryCategories(config) { const { client, owner, name } = check(config); return client.graphql( /* GraphQL */ ` query DiscussionCategories($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { discussionCategories(first: 100) { nodes { id name } } } } `, { owner, name, }); } export function queryByCategoryId(config, { first = 100, categoryId, body = false, bodyHTML = false, bodyText = false, cursor, }) { const { client, owner, name } = check(config); return client.graphql( /* GraphQL */ ` query Discussions( $first: Int! $owner: String! $name: String! $categoryId: ID! $body: Boolean! $bodyHTML: Boolean! $bodyText: Boolean! $cursor: String ) { repository(owner: $owner, name: $name) { discussions( first: $first orderBy: { field: CREATED_AT, direction: DESC } after: $cursor categoryId: $categoryId ) { nodes { author { login url avatarUrl } number title createdAt updatedAt url body @include(if: $body) bodyHTML @include(if: $bodyHTML) bodyText @include(if: $bodyText) labels(first: 5) { nodes { id name color } } } pageInfo { startCursor hasPreviousPage hasNextPage endCursor } totalCount } } } `, { first, owner, name, categoryId, body, bodyHTML, bodyText, cursor, }); } export async function queryByCategoryName(config, params) { const { name, ...rest } = params; const categoriesResponse = await queryCategories(config); const categories = categoriesResponse.repository?.discussionCategories.nodes; const categoryId = categories?.find(category => category.name === name)?.id; if (!categoryId) { return null; } return queryByCategoryId(config, { ...rest, categoryId }); } export async function queryByNumber(config, { number, body = false, bodyHTML = false, bodyText = false }) { const { client, owner, name } = check(config); return client.graphql( /* GraphQL */ ` query Discussion( $owner: String! $name: String! $number: Int! $body: Boolean! $bodyHTML: Boolean! $bodyText: Boolean! ) { repository(owner: $owner, name: $name) { discussion(number: $number) { author { login url avatarUrl } number title createdAt updatedAt url body @include(if: $body) bodyHTML @include(if: $bodyHTML) bodyText @include(if: $bodyText) labels(first: 5) { nodes { id name color } } } } } `, { owner, name, number, body, bodyHTML, bodyText, }); } export function queryLabels(config) { const { client, owner, name } = check(config); return client.graphql( /* GraphQL */ ` query AllLabels($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { labels(first: 100, orderBy: { field: NAME, direction: ASC }) { nodes { id name color } } } } `, { owner, name, }); } export async function search(config, params) { const { client, owner, name } = check(config); const { first = 100, body = false, bodyHTML = false, bodyText = false, cursor, orderBy } = params; let query = `repo:"${owner}/${name}"`; if ('query' in params) { query += ` ${params.query}`; } else { const { label, category } = params; if (label) { query += ` label:"${label}"`; } if (category) { query += ` category:"${category}"`; } } return client .graphql( /* GraphQL */ ` query DiscussionsSearch( $queryStr: String! $first: Int! $body: Boolean! $bodyHTML: Boolean! $bodyText: Boolean! $cursor: String ) { search(first: $first, type: DISCUSSION, query: $queryStr, after: $cursor) { nodes { ... on Discussion { author { login url avatarUrl } number title createdAt updatedAt url body @include(if: $body) bodyHTML @include(if: $bodyHTML) bodyText @include(if: $bodyText) labels(first: 5) { nodes { id color name } } } } pageInfo { startCursor hasPreviousPage hasNextPage endCursor } totalCount: discussionCount } } `, { first, cursor, body, bodyHTML, bodyText, queryStr: query, }) .then(result => { if (orderBy === 'createdAt') { result.search.nodes.sort((a, b) => b.createdAt.localeCompare(a.createdAt)); } return result; }); }