UNPKG

@graphql-inspector/action

Version:

GraphQL Inspector functionality for GitHub Actions

171 lines (170 loc) • 5.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createFileLoader = createFileLoader; exports.createConfigLoader = createConfigLoader; exports.printSchemaFromEndpoint = printSchemaFromEndpoint; exports.loadSources = loadSources; const tslib_1 = require("tslib"); const dataloader_1 = tslib_1.__importDefault(require("dataloader")); const graphql_1 = require("graphql"); const js_yaml_1 = tslib_1.__importDefault(require("js-yaml")); const fetch_1 = require("@whatwg-node/fetch"); const utils_js_1 = require("./utils.js"); function createGetFilesQuery(variableMap) { const variables = Object.keys(variableMap) .map(name => `$${name}: String!`) .join(', '); const files = Object.keys(variableMap) .map(name => { return ` ${name}: object(expression: $${name}) { ... on Blob { text } } `; }) .join('\n'); return /* GraphQL */ ` query GetFile($repo: String!, $owner: String!, ${variables}) { repository(name: $repo, owner: $owner) { ${files} } } `.replace(/\s+/g, ' '); } function createFileLoader(config) { const loader = new dataloader_1.default(async (inputs) => { const variablesMap = (0, utils_js_1.objectFromEntries)(inputs.map(input => [input.alias, `${input.ref}:${input.path}`])); const { context, repo, owner } = config; const result = await context.octokit.graphql(createGetFilesQuery(variablesMap), { repo, owner, ...variablesMap, }); return Promise.all(inputs.map(async (input) => { const alias = input.alias; try { if (!result) { throw new Error(`No result :(`); } if (result.data) { return result.data.repository[alias].text; } return result.repository[alias].text; } catch (error) { const failure = new Error(`Failed to load '${input.path}' (ref: ${input.ref})`); if (input.throwNotFound === false) { if (input.onError) { input.onError(failure); } else { console.error(failure); } return null; } throw failure; } })); }, { batch: true, maxBatchSize: 5, cacheKeyFn(obj) { return `${obj.ref} - ${obj.path}`; }, }); return input => loader.load(input); } function createConfigLoader(config, loadFile) { const loader = new dataloader_1.default(ids => { const errors = []; const onError = (error) => { errors.push(error); }; return Promise.all(ids.map(async (id) => { const [yamlConfig, ymlConfig, pkgFile] = await Promise.all([ loadFile({ ...config, alias: 'yaml', path: `.github/${id}.yaml`, throwNotFound: false, onError, }), loadFile({ ...config, alias: 'yml', path: `.github/${id}.yml`, throwNotFound: false, onError, }), loadFile({ ...config, alias: 'pkg', path: 'package.json', throwNotFound: false, onError, }), ]); if (yamlConfig || ymlConfig) { return js_yaml_1.default.load((yamlConfig || ymlConfig)); } if (pkgFile) { try { const pkg = JSON.parse(pkgFile); if (pkg[id]) { return pkg[id]; } } catch (error) { errors.push(error); } } console.error([`Failed to load config:`, ...errors].join('\n')); return null; })); }, { batch: false, }); return () => loader.load('graphql-inspector'); } async function printSchemaFromEndpoint(endpoint) { const config = (0, utils_js_1.parseEndpoint)(endpoint); const response = await (0, fetch_1.fetch)(config.url, { method: config.method, headers: config.headers, body: JSON.stringify({ query: (0, graphql_1.getIntrospectionQuery)().replace(/\s+/g, ' ').trim(), }), }); const { data } = await response.json(); const introspection = data; return (0, graphql_1.printSchema)((0, graphql_1.buildClientSchema)(introspection, { assumeValid: true, })); } async function loadSources({ config, oldPointer, newPointer, loadFile, }) { // Here, config.endpoint is defined only if target's branch matches branch of environment // otherwise it's empty const useEndpoint = !(0, utils_js_1.isNil)(config.endpoint); const [oldFile, newFile] = await Promise.all([ useEndpoint ? printSchemaFromEndpoint(config.endpoint) : loadFile({ ...oldPointer, alias: 'oldSource', }), loadFile({ ...newPointer, alias: 'newSource', }), ]); return { old: new graphql_1.Source(oldFile, useEndpoint ? typeof config.endpoint === 'string' ? config.endpoint : config.endpoint?.url : `${oldPointer.ref}:${oldPointer.path}`), new: new graphql_1.Source(newFile, `${newPointer.ref}:${newPointer.path}`), }; }