UNPKG

graphql

Version:

A Query Language and Runtime which can target any service.

55 lines 1.99 kB
import { GraphQLError } from "../../error/GraphQLError.mjs"; import { Kind } from "../../language/kinds.mjs"; const MAX_LISTS_DEPTH = 3; export function MaxIntrospectionDepthRule(context) { function checkDepth(node, visitedFragments = Object.create(null), depth = 0) { if (node.kind === Kind.FRAGMENT_SPREAD) { const fragmentName = node.name.value; if (visitedFragments[fragmentName] === true) { return false; } const fragment = context.getFragment(fragmentName); if (!fragment) { return false; } try { visitedFragments[fragmentName] = true; return checkDepth(fragment, visitedFragments, depth); } finally { visitedFragments[fragmentName] = undefined; } } if (node.kind === Kind.FIELD && (node.name.value === 'fields' || node.name.value === 'interfaces' || node.name.value === 'possibleTypes' || node.name.value === 'inputFields')) { depth++; if (depth >= MAX_LISTS_DEPTH) { return true; } } if ('selectionSet' in node && node.selectionSet) { for (const child of node.selectionSet.selections) { if (checkDepth(child, visitedFragments, depth)) { return true; } } } return false; } return { Field(node) { if (node.name.value === '__schema' || node.name.value === '__type') { if (checkDepth(node)) { context.reportError(new GraphQLError('Maximum introspection depth exceeded', { nodes: [node], })); return false; } } }, }; } //# sourceMappingURL=MaxIntrospectionDepthRule.js.map