github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/action/node_modules/@octokit/graphql/README.md (about) 1 # graphql.js 2 3 > GitHub GraphQL API client for browsers and Node 4 5 [](https://www.npmjs.com/package/@octokit/graphql) 6 [](https://github.com/octokit/graphql.js/actions?query=workflow%3ATest+branch%3Amaster) 7 8 <!-- toc --> 9 10 - [Usage](#usage) 11 - [Send a simple query](#send-a-simple-query) 12 - [Authentication](#authentication) 13 - [Variables](#variables) 14 - [Pass query together with headers and variables](#pass-query-together-with-headers-and-variables) 15 - [Use with GitHub Enterprise](#use-with-github-enterprise) 16 - [Use custom `@octokit/request` instance](#use-custom-octokitrequest-instance) 17 - [TypeScript](#typescript) 18 - [Additional Types](#additional-types) 19 - [Errors](#errors) 20 - [Partial responses](#partial-responses) 21 - [Writing tests](#writing-tests) 22 - [License](#license) 23 24 <!-- tocstop --> 25 26 ## Usage 27 28 <table> 29 <tbody valign=top align=left> 30 <tr><th> 31 Browsers 32 </th><td width=100%> 33 34 Load `@octokit/graphql` directly from [cdn.skypack.dev](https://cdn.skypack.dev) 35 36 ```html 37 <script type="module"> 38 import { graphql } from "https://cdn.skypack.dev/@octokit/graphql"; 39 </script> 40 ``` 41 42 </td></tr> 43 <tr><th> 44 Node 45 </th><td> 46 47 Install with <code>npm install @octokit/graphql</code> 48 49 ```js 50 const { graphql } = require("@octokit/graphql"); 51 // or: import { graphql } from "@octokit/graphql"; 52 ``` 53 54 </td></tr> 55 </tbody> 56 </table> 57 58 ### Send a simple query 59 60 ```js 61 const { repository } = await graphql( 62 ` 63 { 64 repository(owner: "octokit", name: "graphql.js") { 65 issues(last: 3) { 66 edges { 67 node { 68 title 69 } 70 } 71 } 72 } 73 } 74 `, 75 { 76 headers: { 77 authorization: `token secret123`, 78 }, 79 } 80 ); 81 ``` 82 83 ### Authentication 84 85 The simplest way to authenticate a request is to set the `Authorization` header, e.g. to a [personal access token](https://github.com/settings/tokens/). 86 87 ```js 88 const graphqlWithAuth = graphql.defaults({ 89 headers: { 90 authorization: `token secret123`, 91 }, 92 }); 93 const { repository } = await graphqlWithAuth(` 94 { 95 repository(owner: "octokit", name: "graphql.js") { 96 issues(last: 3) { 97 edges { 98 node { 99 title 100 } 101 } 102 } 103 } 104 } 105 `); 106 ``` 107 108 For more complex authentication strategies such as GitHub Apps or Basic, we recommend the according authentication library exported by [`@octokit/auth`](https://github.com/octokit/auth.js). 109 110 ```js 111 const { createAppAuth } = require("@octokit/auth-app"); 112 const auth = createAppAuth({ 113 id: process.env.APP_ID, 114 privateKey: process.env.PRIVATE_KEY, 115 installationId: 123, 116 }); 117 const graphqlWithAuth = graphql.defaults({ 118 request: { 119 hook: auth.hook, 120 }, 121 }); 122 123 const { repository } = await graphqlWithAuth( 124 `{ 125 repository(owner: "octokit", name: "graphql.js") { 126 issues(last: 3) { 127 edges { 128 node { 129 title 130 } 131 } 132 } 133 } 134 }` 135 ); 136 ``` 137 138 ### Variables 139 140 ⚠️ Do not use [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) in the query strings as they make your code vulnerable to query injection attacks (see [#2](https://github.com/octokit/graphql.js/issues/2)). Use variables instead: 141 142 ```js 143 const { lastIssues } = await graphql( 144 ` 145 query lastIssues($owner: String!, $repo: String!, $num: Int = 3) { 146 repository(owner: $owner, name: $repo) { 147 issues(last: $num) { 148 edges { 149 node { 150 title 151 } 152 } 153 } 154 } 155 } 156 `, 157 { 158 owner: "octokit", 159 repo: "graphql.js", 160 headers: { 161 authorization: `token secret123`, 162 }, 163 } 164 ); 165 ``` 166 167 ### Pass query together with headers and variables 168 169 ```js 170 const { graphql } = require("@octokit/graphql"); 171 const { lastIssues } = await graphql({ 172 query: `query lastIssues($owner: String!, $repo: String!, $num: Int = 3) { 173 repository(owner:$owner, name:$repo) { 174 issues(last:$num) { 175 edges { 176 node { 177 title 178 } 179 } 180 } 181 } 182 }`, 183 owner: "octokit", 184 repo: "graphql.js", 185 headers: { 186 authorization: `token secret123`, 187 }, 188 }); 189 ``` 190 191 ### Use with GitHub Enterprise 192 193 ```js 194 let { graphql } = require("@octokit/graphql"); 195 graphql = graphql.defaults({ 196 baseUrl: "https://github-enterprise.acme-inc.com/api", 197 headers: { 198 authorization: `token secret123`, 199 }, 200 }); 201 const { repository } = await graphql(` 202 { 203 repository(owner: "acme-project", name: "acme-repo") { 204 issues(last: 3) { 205 edges { 206 node { 207 title 208 } 209 } 210 } 211 } 212 } 213 `); 214 ``` 215 216 ### Use custom `@octokit/request` instance 217 218 ```js 219 const { request } = require("@octokit/request"); 220 const { withCustomRequest } = require("@octokit/graphql"); 221 222 let requestCounter = 0; 223 const myRequest = request.defaults({ 224 headers: { 225 authentication: "token secret123", 226 }, 227 request: { 228 hook(request, options) { 229 requestCounter++; 230 return request(options); 231 }, 232 }, 233 }); 234 const myGraphql = withCustomRequest(myRequest); 235 await request("/"); 236 await myGraphql(` 237 { 238 repository(owner: "acme-project", name: "acme-repo") { 239 issues(last: 3) { 240 edges { 241 node { 242 title 243 } 244 } 245 } 246 } 247 } 248 `); 249 // requestCounter is now 2 250 ``` 251 252 ## TypeScript 253 254 `@octokit/graphql` is exposing proper types for its usage with TypeScript projects. 255 256 ### Additional Types 257 258 Additionally, `GraphQlQueryResponseData` has been exposed to users: 259 260 ```ts 261 import type { GraphQlQueryResponseData } from "@octokit/graphql"; 262 ``` 263 264 ## Errors 265 266 In case of a GraphQL error, `error.message` is set to a combined message describing all errors returned by the endpoint. 267 All errors can be accessed at `error.errors`. `error.request` has the request options such as query, variables and headers set for easier debugging. 268 269 ```js 270 let { graphql, GraphqlResponseError } = require("@octokit/graphql"); 271 graphqlt = graphql.defaults({ 272 headers: { 273 authorization: `token secret123`, 274 }, 275 }); 276 const query = `{ 277 viewer { 278 bioHtml 279 } 280 }`; 281 282 try { 283 const result = await graphql(query); 284 } catch (error) { 285 if (error instanceof GraphqlResponseError) { 286 // do something with the error, allowing you to detect a graphql response error, 287 // compared to accidentally catching unrelated errors. 288 289 // server responds with an object like the following (as an example) 290 // class GraphqlResponseError { 291 // "headers": { 292 // "status": "403", 293 // }, 294 // "data": null, 295 // "errors": [{ 296 // "message": "Field 'bioHtml' doesn't exist on type 'User'", 297 // "locations": [{ 298 // "line": 3, 299 // "column": 5 300 // }] 301 // }] 302 // } 303 304 console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } } 305 console.log(error.message); // Field 'bioHtml' doesn't exist on type 'User' 306 } else { 307 // handle non-GraphQL error 308 } 309 } 310 ``` 311 312 ## Partial responses 313 314 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` 315 316 ```js 317 let { graphql } = require("@octokit/graphql"); 318 graphql = graphql.defaults({ 319 headers: { 320 authorization: `token secret123`, 321 }, 322 }); 323 const query = `{ 324 repository(name: "probot", owner: "probot") { 325 name 326 ref(qualifiedName: "master") { 327 target { 328 ... on Commit { 329 history(first: 25, after: "invalid cursor") { 330 nodes { 331 message 332 } 333 } 334 } 335 } 336 } 337 } 338 }`; 339 340 try { 341 const result = await graphql(query); 342 } catch (error) { 343 // server responds with 344 // { 345 // "data": { 346 // "repository": { 347 // "name": "probot", 348 // "ref": null 349 // } 350 // }, 351 // "errors": [ 352 // { 353 // "type": "INVALID_CURSOR_ARGUMENTS", 354 // "path": [ 355 // "repository", 356 // "ref", 357 // "target", 358 // "history" 359 // ], 360 // "locations": [ 361 // { 362 // "line": 7, 363 // "column": 11 364 // } 365 // ], 366 // "message": "`invalid cursor` does not appear to be a valid cursor." 367 // } 368 // ] 369 // } 370 371 console.log("Request failed:", error.request); // { query, variables: {}, headers: { authorization: 'token secret123' } } 372 console.log(error.message); // `invalid cursor` does not appear to be a valid cursor. 373 console.log(error.data); // { repository: { name: 'probot', ref: null } } 374 } 375 ``` 376 377 ## Writing tests 378 379 You can pass a replacement for [the built-in fetch implementation](https://github.com/bitinn/node-fetch) as `request.fetch` option. For example, using [fetch-mock](http://www.wheresrhys.co.uk/fetch-mock/) works great to write tests 380 381 ```js 382 const assert = require("assert"); 383 const fetchMock = require("fetch-mock/es5/server"); 384 385 const { graphql } = require("@octokit/graphql"); 386 387 graphql("{ viewer { login } }", { 388 headers: { 389 authorization: "token secret123", 390 }, 391 request: { 392 fetch: fetchMock 393 .sandbox() 394 .post("https://api.github.com/graphql", (url, options) => { 395 assert.strictEqual(options.headers.authorization, "token secret123"); 396 assert.strictEqual( 397 options.body, 398 '{"query":"{ viewer { login } }"}', 399 "Sends correct query" 400 ); 401 return { data: {} }; 402 }), 403 }, 404 }); 405 ``` 406 407 ## License 408 409 [MIT](LICENSE)