From fbb6ec28dbf99d9b9e84cfa8792f1f3b14998d19 Mon Sep 17 00:00:00 2001 From: William Chargin Date: Thu, 5 Apr 2018 00:08:52 -0700 Subject: [PATCH] Extract GitHub GraphQL code to a module (#119) Summary: Per #117, we want to develop an ad hoc pagination API written specifically against the query that we use to interact with GitHub. The pagination logic should be separate from the logic to actually fetch the repo, but should be colocated with the query itself, so this commit extricates the query from `fetchGithubRepo.js` into a new module. Test Plan: Existing tests pass, including `fetchGithubRepoTest.sh`. wchargin-branch: extract-github-graphql --- src/plugins/github/fetchGithubRepo.js | 95 ++------------------------- src/plugins/github/graphql.js | 92 ++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 91 deletions(-) create mode 100644 src/plugins/github/graphql.js diff --git a/src/plugins/github/fetchGithubRepo.js b/src/plugins/github/fetchGithubRepo.js index d09a8e0..789a20e 100644 --- a/src/plugins/github/fetchGithubRepo.js +++ b/src/plugins/github/fetchGithubRepo.js @@ -6,8 +6,8 @@ import fetch from "isomorphic-fetch"; -import type {Body} from "../../graphql/queries"; -import * as GraphQLQueries from "../../graphql/queries"; +import {stringify, inlineLayout} from "../../graphql/queries"; +import {createQuery, createVariables} from "./graphql"; /** * Scrape data from a GitHub repo using the GitHub API. @@ -45,101 +45,14 @@ export default function fetchGithubRepo( throw new Error(`Invalid token: ${token}`); } - const query = GraphQLQueries.stringify.body( - createQuery(), - GraphQLQueries.inlineLayout() - ); - const variables = {repoOwner, repoName}; + const query = stringify.body(createQuery(), inlineLayout()); + const variables = createVariables(repoOwner, repoName); const payload = {query, variables}; return postQuery(payload, token); } const GITHUB_GRAPHQL_SERVER = "https://api.github.com/graphql"; -function createQuery(): Body { - const b = GraphQLQueries.build; - const makePageInfo = () => b.field("pageInfo", {}, [b.field("hasNextPage")]); - const makeAuthor = () => b.field("author", {}, [b.fragmentSpread("whoami")]); - const body: Body = [ - b.query( - "FetchData", - [b.param("repoOwner", "String!"), b.param("repoName", "String!")], - [ - b.field( - "repository", - {owner: b.variable("repoOwner"), name: b.variable("repoName")}, - [ - b.field("issues", {first: b.literal(100)}, [ - makePageInfo(), - b.field("nodes", {}, [ - b.field("id"), - b.field("title"), - b.field("body"), - b.field("number"), - makeAuthor(), - b.field("comments", {first: b.literal(20)}, [ - makePageInfo(), - b.field("nodes", {}, [ - b.field("id"), - makeAuthor(), - b.field("body"), - b.field("url"), - ]), - ]), - ]), - ]), - b.field("pullRequests", {first: b.literal(100)}, [ - makePageInfo(), - b.field("nodes", {}, [ - b.field("id"), - b.field("title"), - b.field("body"), - b.field("number"), - makeAuthor(), - b.field("comments", {first: b.literal(20)}, [ - makePageInfo(), - b.field("nodes", {}, [ - b.field("id"), - makeAuthor(), - b.field("body"), - b.field("url"), - ]), - ]), - b.field("reviews", {first: b.literal(10)}, [ - makePageInfo(), - b.field("nodes", {}, [ - b.field("id"), - b.field("body"), - makeAuthor(), - b.field("state"), - b.field("comments", {first: b.literal(10)}, [ - makePageInfo(), - b.field("nodes", {}, [ - b.field("id"), - b.field("body"), - b.field("url"), - makeAuthor(), - ]), - ]), - ]), - ]), - ]), - ]), - ] - ), - ] - ), - b.fragment("whoami", "Actor", [ - b.field("__typename"), - b.field("login"), - b.inlineFragment("User", [b.field("id")]), - b.inlineFragment("Organization", [b.field("id")]), - b.inlineFragment("Bot", [b.field("id")]), - ]), - ]; - return body; -} - function postQuery(payload, token) { return fetch(GITHUB_GRAPHQL_SERVER, { method: "POST", diff --git a/src/plugins/github/graphql.js b/src/plugins/github/graphql.js new file mode 100644 index 0000000..11a622a --- /dev/null +++ b/src/plugins/github/graphql.js @@ -0,0 +1,92 @@ +// @flow + +import type {Body} from "../../graphql/queries"; +import {build} from "../../graphql/queries"; + +export function createQuery(): Body { + const b = build; + const makePageInfo = () => b.field("pageInfo", {}, [b.field("hasNextPage")]); + const makeAuthor = () => b.field("author", {}, [b.fragmentSpread("whoami")]); + const body: Body = [ + b.query( + "FetchData", + [b.param("repoOwner", "String!"), b.param("repoName", "String!")], + [ + b.field( + "repository", + {owner: b.variable("repoOwner"), name: b.variable("repoName")}, + [ + b.field("issues", {first: b.literal(100)}, [ + makePageInfo(), + b.field("nodes", {}, [ + b.field("id"), + b.field("title"), + b.field("body"), + b.field("number"), + makeAuthor(), + b.field("comments", {first: b.literal(20)}, [ + makePageInfo(), + b.field("nodes", {}, [ + b.field("id"), + makeAuthor(), + b.field("body"), + b.field("url"), + ]), + ]), + ]), + ]), + b.field("pullRequests", {first: b.literal(100)}, [ + makePageInfo(), + b.field("nodes", {}, [ + b.field("id"), + b.field("title"), + b.field("body"), + b.field("number"), + makeAuthor(), + b.field("comments", {first: b.literal(20)}, [ + makePageInfo(), + b.field("nodes", {}, [ + b.field("id"), + makeAuthor(), + b.field("body"), + b.field("url"), + ]), + ]), + b.field("reviews", {first: b.literal(10)}, [ + makePageInfo(), + b.field("nodes", {}, [ + b.field("id"), + b.field("body"), + makeAuthor(), + b.field("state"), + b.field("comments", {first: b.literal(10)}, [ + makePageInfo(), + b.field("nodes", {}, [ + b.field("id"), + b.field("body"), + b.field("url"), + makeAuthor(), + ]), + ]), + ]), + ]), + ]), + ]), + ] + ), + ] + ), + b.fragment("whoami", "Actor", [ + b.field("__typename"), + b.field("login"), + b.inlineFragment("User", [b.field("id")]), + b.inlineFragment("Organization", [b.field("id")]), + b.inlineFragment("Bot", [b.field("id")]), + ]), + ]; + return body; +} + +export function createVariables(repoOwner: string, repoName: string) { + return {repoOwner, repoName}; +}