Socket
Socket
Sign inDemoInstall

@octokit/graphql

Package Overview
Dependencies
6
Maintainers
4
Versions
59
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    @octokit/graphql

GitHub GraphQL API client for browsers and Node


Version published
Weekly downloads
6.3M
decreased by-17.46%
Maintainers
4
Install size
4.65 MB
Created
Weekly downloads
 

Package description

What is @octokit/graphql?

The @octokit/graphql npm package is designed to simplify making GraphQL queries to the GitHub API. It provides a straightforward way to execute queries and mutations, handle authentication, and manage GraphQL variables. This package is part of the Octokit suite, which is officially maintained by GitHub, ensuring high compatibility and reliability for developers interacting with GitHub's data.

What are @octokit/graphql's main functionalities?

Executing a GraphQL query

This feature allows you to execute a basic GraphQL query to fetch the login name of the authenticated GitHub user. You need to replace 'YOUR_GITHUB_TOKEN' with your actual GitHub token.

{
  "query": "query { viewer { login }}",
  "headers": {
    "authorization": "token YOUR_GITHUB_TOKEN"
  }
}

Executing a GraphQL mutation

This feature demonstrates how to execute a mutation to create a new issue in a repository. You need to replace 'REPOSITORY_ID' and 'YOUR_GITHUB_TOKEN' with your repository's ID and your GitHub token, respectively.

{
  "mutation": "mutation ($repositoryId: ID!, $issueTitle: String!) { createIssue(input: {repositoryId: $repositoryId, title: $issueTitle}) { issue { id } } }",
  "variables": {
    "repositoryId": "REPOSITORY_ID",
    "issueTitle": "New Issue Title"
  },
  "headers": {
    "authorization": "token YOUR_GITHUB_TOKEN"
  }
}

Other packages similar to @octokit/graphql

Readme

Source

graphql.js

GitHub GraphQL API client for browsers and Node

@latest Build Status

Usage

Browsers

Load @octokit/graphql directly from esm.sh

<script type="module">
  import { graphql } from "https://esm.sh/@octokit/graphql";
</script>
Node

Install with npm install @octokit/graphql

import { graphql } from "@octokit/graphql";

Send a simple query

const { repository } = await graphql(
  `
    {
      repository(owner: "octokit", name: "graphql.js") {
        issues(last: 3) {
          edges {
            node {
              title
            }
          }
        }
      }
    }
  `,
  {
    headers: {
      authorization: `token secret123`,
    },
  },
);

Authentication

The simplest way to authenticate a request is to set the Authorization header, e.g. to a personal access token.

const graphqlWithAuth = graphql.defaults({
  headers: {
    authorization: `token secret123`,
  },
});
const { repository } = await graphqlWithAuth(`
  {
    repository(owner: "octokit", name: "graphql.js") {
      issues(last: 3) {
        edges {
          node {
            title
          }
        }
      }
    }
  }
`);

For more complex authentication strategies such as GitHub Apps or Basic, we recommend the according authentication library exported by @octokit/auth.

const { createAppAuth } = await import("@octokit/auth-app");
const auth = createAppAuth({
  appId: process.env.APP_ID,
  privateKey: process.env.PRIVATE_KEY,
  installationId: 123,
});
const graphqlWithAuth = graphql.defaults({
  request: {
    hook: auth.hook,
  },
});

const { repository } = await graphqlWithAuth(
  `{
    repository(owner: "octokit", name: "graphql.js") {
      issues(last: 3) {
        edges {
          node {
            title
          }
        }
      }
    }
  }`,
);

Variables

⚠️ Do not use template literals in the query strings as they make your code vulnerable to query injection attacks (see #2). Use variables instead:

const { repository } = await graphql(
  `
    query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {
      repository(owner: $owner, name: $repo) {
        issues(last: $num) {
          edges {
            node {
              title
            }
          }
        }
      }
    }
  `,
  {
    owner: "octokit",
    repo: "graphql.js",
    headers: {
      authorization: `token secret123`,
    },
  },
);

Pass query together with headers and variables

import { graphql } from("@octokit/graphql");
const { repository } = await graphql({
  query: `query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {
    repository(owner: $owner, name: $repo) {
      issues(last: $num) {
        edges {
          node {
            title
          }
        }
      }
    }
  }`,
  owner: "octokit",
  repo: "graphql.js",
  headers: {
    authorization: `token secret123`,
  },
});

Use with GitHub Enterprise

import { graphql } from "@octokit/graphql";
graphql = graphql.defaults({
  baseUrl: "https://github-enterprise.acme-inc.com/api",
  headers: {
    authorization: `token secret123`,
  },
});
const { repository } = await graphql(`
  {
    repository(owner: "acme-project", name: "acme-repo") {
      issues(last: 3) {
        edges {
          node {
            title
          }
        }
      }
    }
  }
`);

Use custom @octokit/request instance

import { request } from "@octokit/request";
import { withCustomRequest } from "@octokit/graphql";

let requestCounter = 0;
const myRequest = request.defaults({
  headers: {
    authorization: "bearer secret123",
  },
  request: {
    hook(request, options) {
      requestCounter++;
      return request(options);
    },
  },
});
const myGraphql = withCustomRequest(myRequest);
await request("/");
await myGraphql(`
  {
    repository(owner: "acme-project", name: "acme-repo") {
      issues(last: 3) {
        edges {
          node {
            title
          }
        }
      }
    }
  }
`);
// requestCounter is now 2

TypeScript

@octokit/graphql is exposing proper types for its usage with TypeScript projects.

Additional Types

Additionally, GraphQlQueryResponseData has been exposed to users:

import type { GraphQlQueryResponseData } from "@octokit/graphql";

Errors

In case of a GraphQL error, error.message is set to a combined message describing all errors returned by the endpoint. All errors can be accessed at error.errors. error.request has the request options such as query, variables and headers set for easier debugging.

import { graphql, GraphqlResponseError } from "@octokit/graphql";
graphql = graphql.defaults({
  headers: {
    authorization: `token secret123`,
  },
});
const query = `{
  viewer {
    bioHtml
  }
}`;

try {
  const result = await graphql(query);
} catch (error) {
  if (error instanceof GraphqlResponseError) {
    // do something with the error, allowing you to detect a graphql response error,
    // compared to accidentally catching unrelated errors.

    // server responds with an object like the following (as an example)
    // class GraphqlResponseError {
    //  "headers": {
    //    "status": "403",
    //  },
    //  "data": null,
    //  "errors": [{
    //   "message": "Field 'bioHtml' doesn't exist on type 'User'",
    //   "locations": [{
    //    "line": 3,
    //    "column": 5
    //   }]
    //  }]
    // }

    console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } }
    console.log(error.message); // Field 'bioHtml' doesn't exist on type 'User'
  } else {
    // handle non-GraphQL error
  }
}

Partial responses

A GraphQL query may respond with partial data accompanied by errors. In this case we will throw an error but the partial data will still be accessible through error.data

import { graphql } from "@octokit/graphql";
graphql = graphql.defaults({
  headers: {
    authorization: `token secret123`,
  },
});
const query = `{
  repository(name: "probot", owner: "probot") {
    name
    ref(qualifiedName: "master") {
      target {
        ... on Commit {
          history(first: 25, after: "invalid cursor") {
            nodes {
              message
            }
          }
        }
      }
    }
  }
}`;

try {
  const result = await graphql(query);
} catch (error) {
  // server responds with
  // {
  //   "data": {
  //     "repository": {
  //       "name": "probot",
  //       "ref": null
  //     }
  //   },
  //   "errors": [
  //     {
  //       "type": "INVALID_CURSOR_ARGUMENTS",
  //       "path": [
  //         "repository",
  //         "ref",
  //         "target",
  //         "history"
  //       ],
  //       "locations": [
  //         {
  //           "line": 7,
  //           "column": 11
  //         }
  //       ],
  //       "message": "`invalid cursor` does not appear to be a valid cursor."
  //     }
  //   ]
  // }

  console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } }
  console.log(error.message); // `invalid cursor` does not appear to be a valid cursor.
  console.log(error.data); // { repository: { name: 'probot', ref: null } }
}

Writing tests

You can pass a replacement for the built-in fetch implementation as request.fetch option. For example, using fetch-mock works great to write tests

import assert from "assert";
import fetchMock from "fetch-mock";

import { graphql } from "@octokit/graphql";

graphql("{ viewer { login } }", {
  headers: {
    authorization: "token secret123",
  },
  request: {
    fetch: fetchMock
      .sandbox()
      .post("https://api.github.com/graphql", (url, options) => {
        assert.strictEqual(options.headers.authorization, "token secret123");
        assert.strictEqual(
          options.body,
          '{"query":"{ viewer { login } }"}',
          "Sends correct query",
        );
        return { data: {} };
      }),
  },
});

License

MIT

Keywords

FAQs

Last updated on 15 Apr 2024

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc