UNPKG

@graphql-tools/github-loader

Version:

A set of utils for faster development of GraphQL tools

145 lines (144 loc) 5.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GithubLoader = void 0; const tslib_1 = require("tslib"); const graphql_1 = require("graphql"); const value_or_promise_1 = require("value-or-promise"); const sync_fetch_1 = tslib_1.__importDefault(require("@ardatan/sync-fetch")); const graphql_tag_pluck_1 = require("@graphql-tools/graphql-tag-pluck"); const utils_1 = require("@graphql-tools/utils"); const fetch_1 = require("@whatwg-node/fetch"); // github:owner/name#ref:path/to/file function extractData(pointer) { const [repo, file] = pointer.split('#'); const [owner, name] = repo.split(':')[1].split('/'); const [ref, path] = file.split(':'); return { owner, name, ref, path, }; } /** * This loader loads a file from GitHub. * * ```js * const typeDefs = await loadTypedefs('github:githubUser/githubRepo#branchName:path/to/file.ts', { * loaders: [new GithubLoader()], * token: YOUR_GITHUB_TOKEN, * }) * ``` */ class GithubLoader { async canLoad(pointer) { return this.canLoadSync(pointer); } canLoadSync(pointer) { return typeof pointer === 'string' && pointer.toLowerCase().startsWith('github:'); } loadSyncOrAsync(pointer, options, fetchFn) { if (!this.canLoadSync(pointer)) { return []; } const { owner, name, ref, path } = extractData(pointer); return new value_or_promise_1.ValueOrPromise(() => fetchFn('https://api.github.com/graphql', this.prepareRequest({ owner, ref, path, name, options }))) .then(response => { const contentType = response.headers.get('content-type'); if (contentType && contentType.includes('application/json')) { return response.json(); } else { return response.text(); } }) .then(response => { const status = response.status; return this.handleResponse({ pointer, path, options, response, status }); }) .resolve(); } load(pointer, options) { const fetchFn = options.customFetch || fetch_1.fetch; return this.loadSyncOrAsync(pointer, options, fetchFn); } loadSync(pointer, options) { const fetchFn = options.customFetch || sync_fetch_1.default; return this.loadSyncOrAsync(pointer, options, fetchFn); } handleResponse({ pointer, path, options, response, status, }) { let errorMessage = null; if (response.errors && response.errors.length > 0) { errorMessage = response.errors.map((item) => item.message).join(', '); } else if (status === 401) { errorMessage = response.message; } else if (response.message) { errorMessage = response.message; } else if (!response.data) { errorMessage = response; } if (errorMessage) { throw new Error('Unable to download schema from github: ' + errorMessage); } if (!response.data.repository.object) { throw new Error(`Unable to find file: ${path} on ${pointer.replace(`:${path}`, '')}`); } const content = response.data.repository.object.text; if (/\.(gql|graphql)s?$/i.test(path)) { return [(0, utils_1.parseGraphQLSDL)(pointer, content, options)]; } if (/\.json$/i.test(path)) { return [(0, utils_1.parseGraphQLJSON)(pointer, content, options)]; } if (path.endsWith('.tsx') || path.endsWith('.ts') || path.endsWith('.js') || path.endsWith('.jsx')) { const sources = (0, graphql_tag_pluck_1.gqlPluckFromCodeStringSync)(pointer, content, options.pluckConfig); return sources.map(source => ({ location: pointer, document: (0, graphql_1.parse)(source, options), })); } throw new Error(`Invalid file extension: ${path}`); } prepareRequest({ owner, ref, path, name, options, }) { const token = options.token || globalThis.process?.env?.['GITHUB_TOKEN']; if (!token) { throw new Error('You must provide a token to use the GitHub loader'); } const headers = { 'content-type': 'application/json; charset=utf-8', 'user-agent': 'graphql-tools', authorization: `bearer ${token}`, ...options.headers, }; return { method: 'POST', headers, body: JSON.stringify({ query: ` query GetGraphQLSchemaForGraphQLtools($owner: String!, $name: String!, $expression: String!) { repository(owner: $owner, name: $name) { object(expression: $expression) { ... on Blob { text } } } } `, variables: { owner, name, expression: ref + ':' + path, }, operationName: 'GetGraphQLSchemaForGraphQLtools', }), }; } } exports.GithubLoader = GithubLoader;