graphql.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { GraphqlResponseError } from "./error";
  2. const NON_VARIABLE_OPTIONS = [
  3. "method",
  4. "baseUrl",
  5. "url",
  6. "headers",
  7. "request",
  8. "query",
  9. "mediaType",
  10. ];
  11. const FORBIDDEN_VARIABLE_OPTIONS = ["query", "method", "url"];
  12. const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/;
  13. export function graphql(request, query, options) {
  14. if (options) {
  15. if (typeof query === "string" && "query" in options) {
  16. return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`));
  17. }
  18. for (const key in options) {
  19. if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key))
  20. continue;
  21. return Promise.reject(new Error(`[@octokit/graphql] "${key}" cannot be used as variable name`));
  22. }
  23. }
  24. const parsedOptions = typeof query === "string" ? Object.assign({ query }, options) : query;
  25. const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {
  26. if (NON_VARIABLE_OPTIONS.includes(key)) {
  27. result[key] = parsedOptions[key];
  28. return result;
  29. }
  30. if (!result.variables) {
  31. result.variables = {};
  32. }
  33. result.variables[key] = parsedOptions[key];
  34. return result;
  35. }, {});
  36. // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix
  37. // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451
  38. const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;
  39. if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {
  40. requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql");
  41. }
  42. return request(requestOptions).then((response) => {
  43. if (response.data.errors) {
  44. const headers = {};
  45. for (const key of Object.keys(response.headers)) {
  46. headers[key] = response.headers[key];
  47. }
  48. throw new GraphqlResponseError(requestOptions, headers, response.data);
  49. }
  50. return response.data.data;
  51. });
  52. }