UNPKG

4.54 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.GithubLoader = void 0;
4const tslib_1 = require("tslib");
5const utils_1 = require("@graphql-tools/utils");
6const graphql_tag_pluck_1 = require("@graphql-tools/graphql-tag-pluck");
7const graphql_1 = require("graphql");
8const sync_fetch_1 = tslib_1.__importDefault(require("@ardatan/sync-fetch"));
9const fetch_1 = require("@whatwg-node/fetch");
10// github:owner/name#ref:path/to/file
11function extractData(pointer) {
12 const [repo, file] = pointer.split('#');
13 const [owner, name] = repo.split(':')[1].split('/');
14 const [ref, path] = file.split(':');
15 return {
16 owner,
17 name,
18 ref,
19 path,
20 };
21}
22/**
23 * This loader loads a file from GitHub.
24 *
25 * ```js
26 * const typeDefs = await loadTypedefs('github:githubUser/githubRepo#branchName:path/to/file.ts', {
27 * loaders: [new GithubLoader()],
28 * token: YOUR_GITHUB_TOKEN,
29 * })
30 * ```
31 */
32class GithubLoader {
33 async canLoad(pointer) {
34 return this.canLoadSync(pointer);
35 }
36 canLoadSync(pointer) {
37 return typeof pointer === 'string' && pointer.toLowerCase().startsWith('github:');
38 }
39 async load(pointer, options) {
40 if (!(await this.canLoad(pointer))) {
41 return [];
42 }
43 const { owner, name, ref, path } = extractData(pointer);
44 const fetch = options.customFetch || fetch_1.fetch;
45 const request = await fetch('https://api.github.com/graphql', this.prepareRequest({ owner, ref, path, name, options }));
46 const response = await request.json();
47 const status = request.status;
48 return this.handleResponse({ pointer, path, options, response, status });
49 }
50 loadSync(pointer, options) {
51 if (!this.canLoadSync(pointer)) {
52 return [];
53 }
54 const { owner, name, ref, path } = extractData(pointer);
55 const fetch = options.customFetch || sync_fetch_1.default;
56 const request = fetch('https://api.github.com/graphql', this.prepareRequest({ owner, ref, path, name, options }));
57 const response = request.json();
58 const status = request.status;
59 return this.handleResponse({ pointer, path, options, response, status });
60 }
61 handleResponse({ pointer, path, options, response, status, }) {
62 let errorMessage = null;
63 if (response.errors && response.errors.length > 0) {
64 errorMessage = response.errors.map((item) => item.message).join(', ');
65 }
66 else if (status === 401) {
67 errorMessage = response.message;
68 }
69 else if (!response.data) {
70 errorMessage = response;
71 }
72 if (errorMessage) {
73 throw new Error('Unable to download schema from github: ' + errorMessage);
74 }
75 const content = response.data.repository.object.text;
76 if (/\.(gql|graphql)s?$/i.test(path)) {
77 return [(0, utils_1.parseGraphQLSDL)(pointer, content, options)];
78 }
79 if (/\.json$/i.test(path)) {
80 return [(0, utils_1.parseGraphQLJSON)(pointer, content, options)];
81 }
82 if (path.endsWith('.tsx') || path.endsWith('.ts') || path.endsWith('.js') || path.endsWith('.jsx')) {
83 const sources = (0, graphql_tag_pluck_1.gqlPluckFromCodeStringSync)(pointer, content, options.pluckConfig);
84 return sources.map(source => ({
85 location: pointer,
86 document: (0, graphql_1.parse)(source, options),
87 }));
88 }
89 throw new Error(`Invalid file extension: ${path}`);
90 }
91 prepareRequest({ owner, ref, path, name, options, }) {
92 return {
93 method: 'POST',
94 headers: {
95 'content-type': 'application/json; charset=utf-8',
96 authorization: `bearer ${options.token}`,
97 },
98 body: JSON.stringify({
99 query: `
100 query GetGraphQLSchemaForGraphQLtools($owner: String!, $name: String!, $expression: String!) {
101 repository(owner: $owner, name: $name) {
102 object(expression: $expression) {
103 ... on Blob {
104 text
105 }
106 }
107 }
108 }
109 `,
110 variables: {
111 owner,
112 name,
113 expression: ref + ':' + path,
114 },
115 operationName: 'GetGraphQLSchemaForGraphQLtools',
116 }),
117 };
118 }
119}
120exports.GithubLoader = GithubLoader;