diff --git a/src/utilities/__tests__/getIntrospectionQuery-test.ts b/src/utilities/__tests__/getIntrospectionQuery-test.ts index 656412022c..fe7742e9b4 100644 --- a/src/utilities/__tests__/getIntrospectionQuery-test.ts +++ b/src/utilities/__tests__/getIntrospectionQuery-test.ts @@ -176,4 +176,10 @@ describe('getIntrospectionQuery', () => { .toNotContain('directives(includeDeprecated: true) {') .toMatch('deprecationReason', 2); }); + + it('throw error if typeDepth is too high', () => { + expect(() => getIntrospectionQuery({ typeDepth: 101 })).to.throw( + 'Please set typeDepth to a reasonable value between 0 and 100; the default is 9.', + ); + }); }); diff --git a/src/utilities/getIntrospectionQuery.ts b/src/utilities/getIntrospectionQuery.ts index d4bca051c1..761b50c7ef 100644 --- a/src/utilities/getIntrospectionQuery.ts +++ b/src/utilities/getIntrospectionQuery.ts @@ -44,6 +44,16 @@ export interface IntrospectionOptions { * Default: false */ oneOf?: boolean; + + /** + * How deep to recurse into nested types, larger values will result in more + * accurate results, but have a higher load on the server. + * Some servers might restrict the maximum query depth or complexity. + * If that's the case, try decreasing this value. + * + * Default: 9 + */ + typeDepth?: number; } /** @@ -59,6 +69,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string { inputValueDeprecation: false, experimentalDirectiveDeprecation: false, oneOf: false, + typeDepth: 9, ...options, }; @@ -80,6 +91,21 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string { return optionsWithDefault.experimentalDirectiveDeprecation ? str : ''; } const oneOf = optionsWithDefault.oneOf ? 'isOneOf' : ''; + function ofType(level: number, indent: string): string { + if (level <= 0) { + return ''; + } + if (level > 100) { + throw new Error( + 'Please set typeDepth to a reasonable value between 0 and 100; the default is 9.', + ); + } + return ` +${indent}ofType { +${indent} name +${indent} kind${ofType(level - 1, indent + ' ')} +${indent}}`; + } return ` query IntrospectionQuery { @@ -153,43 +179,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string { fragment TypeRef on __Type { kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - } - } - } - } - } - } - } - } - } + name${ofType(optionsWithDefault.typeDepth, ' ')} } `; }