@graphql-inspector/action
Version:
GraphQL Inspector functionality for GitHub Actions
150 lines (149 loc) • 6.15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadSources = exports.printSchemaFromEndpoint = exports.createConfigLoader = exports.createFileLoader = void 0;
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((inputs) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const variablesMap = (0, utils_js_1.objectFromEntries)(inputs.map(input => [input.alias, `${input.ref}:${input.path}`]));
const { context, repo, owner } = config;
const result = yield context.octokit.graphql(createGetFilesQuery(variablesMap), Object.assign({ repo,
owner }, variablesMap));
return Promise.all(inputs.map((input) => tslib_1.__awaiter(this, void 0, void 0, function* () {
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);
}
exports.createFileLoader = createFileLoader;
function createConfigLoader(config, loadFile) {
const loader = new dataloader_1.default(ids => {
const errors = [];
const onError = (error) => {
errors.push(error);
};
return Promise.all(ids.map((id) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const [yamlConfig, ymlConfig, pkgFile] = yield Promise.all([
loadFile(Object.assign(Object.assign({}, config), { alias: 'yaml', path: `.github/${id}.yaml`, throwNotFound: false, onError })),
loadFile(Object.assign(Object.assign({}, config), { alias: 'yml', path: `.github/${id}.yml`, throwNotFound: false, onError })),
loadFile(Object.assign(Object.assign({}, 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');
}
exports.createConfigLoader = createConfigLoader;
function printSchemaFromEndpoint(endpoint) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const config = (0, utils_js_1.parseEndpoint)(endpoint);
const response = yield (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 } = yield response.json();
const introspection = data;
return (0, graphql_1.printSchema)((0, graphql_1.buildClientSchema)(introspection, {
assumeValid: true,
}));
});
}
exports.printSchemaFromEndpoint = printSchemaFromEndpoint;
function loadSources({ config, oldPointer, newPointer, loadFile, }) {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
// 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] = yield Promise.all([
useEndpoint
? printSchemaFromEndpoint(config.endpoint)
: loadFile(Object.assign(Object.assign({}, oldPointer), { alias: 'oldSource' })),
loadFile(Object.assign(Object.assign({}, newPointer), { alias: 'newSource' })),
]);
return {
old: new graphql_1.Source(oldFile, useEndpoint
? typeof config.endpoint === 'string'
? config.endpoint
: (_a = config.endpoint) === null || _a === void 0 ? void 0 : _a.url
: `${oldPointer.ref}:${oldPointer.path}`),
new: new graphql_1.Source(newFile, `${newPointer.ref}:${newPointer.path}`),
};
});
}
exports.loadSources = loadSources;