Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 3x 12x 11x 2x 2x 12x 12x 12x 12x 12x 12x 12x 12x 3x 9x 9x 9x 8x 8x 1x 7x 7x 7x 7x 6x 1x 7x 6x 3x 1x 2x 3x | const { getAxios } = require('./axiosLoader');
async function runAuthTest(axios, token, debug, timeout) {
const testRes = await axios.post(
'https://api.github.com/graphql',
{ query: '{ viewer { login } }' },
{ headers: { Authorization: token ? `Bearer ${token}` : undefined }, timeout: timeout || 8000 }
);
if (!testRes || !testRes.data || !testRes.data.data || !testRes.data.data.viewer) {
if (debug) console.log('fetchGithub: auth test response', testRes && testRes.data);
throw new Error('GraphQL auth test failed');
}
}
/**
* Runs a GitHub GraphQL query, preceded by a lightweight auth test to surface
* token errors with a clear message before the real query fires.
* Extracts repository nodes from either a pinnedItems or repositories response shape.
*
* @param {string} token - GitHub personal access token
* @param {string} query - GraphQL query string
* @param {object} [variables] - Query variables; only attached to the payload when the query uses '$' parameters
* @param {object} [opts] - Optional overrides: { timeout }
* @returns {Promise<object[]>} Array of repository nodes
*/
async function runGraphQL(token, query, variables = { login: 'keglev' }, opts = {}) {
const axios = getAxios();
Iif (!axios) throw new Error('fetchGithub: failed to require axios (is it installed?)');
const DEBUG = process.env.DEBUG_FETCH === '1' || process.env.DEBUG_FETCH === 'true';
const timeout = (opts && opts.timeout) || 10000;
// Only include variables when the query declares parameters; bare queries reject extra variables
const payload = (typeof query === 'string' && query.includes('$')) ? { query, variables } : { query };
try {
if (DEBUG) console.log('fetchGithub: running auth test');
await runAuthTest(axios, token, DEBUG, timeout);
} catch (e) {
throw new Error('GraphQL auth/test query failed: ' + (e && e.message));
}
try {
if (DEBUG) console.log('fetchGithub: sending query, variables:', variables);
const res = await axios.post('https://api.github.com/graphql', payload, { headers: { Authorization: token ? `Bearer ${token}` : undefined }, timeout });
if (DEBUG) try { console.log('fetchGithub: response status', res && res.status); } catch (err) {}
if (res && res.data && res.data.errors && res.data.errors.length) {
throw new Error('GraphQL errors: ' + JSON.stringify(res.data.errors));
}
const body = res && res.data ? res.data : null;
const user = body && body.data && body.data.user;
let nodes = null;
if (user) {
if (user.pinnedItems && Array.isArray(user.pinnedItems.nodes)) nodes = user.pinnedItems.nodes;
else Eif (user.repositories && Array.isArray(user.repositories.nodes)) nodes = user.repositories.nodes;
}
if (!Array.isArray(nodes)) throw new Error('Invalid GraphQL response: ' + JSON.stringify(body));
return nodes;
} catch (err) {
if (err && err.response && err.response.data) {
throw new Error('GraphQL request failed: ' + JSON.stringify(err.response.data, null, 2));
}
throw new Error((err && err.message) || String(err));
}
}
module.exports = { runGraphQL };
|