import { GraphQLField } from 'graphql' import { ArgsValue, GetGen, RootValue } from '../core' import { plugin } from '../plugin' import { printedGenTyping, printedGenTypingImport } from '../utils' const QueryComplexityImport = printedGenTypingImport({ module: '@nexus/schema/dist/plugins/queryComplexityPlugin', bindings: ['QueryComplexity'], }) const fieldDefTypes = printedGenTyping({ optional: true, name: 'complexity', description: ` The complexity for an individual field. Return a number or a function that returns a number to specify the complexity for this field. `, type: 'QueryComplexity', imports: [QueryComplexityImport], }) export type QueryComplexityEstimatorArgs = { type: RootValue field: GraphQLField, GetGen<'context'>, ArgsValue> args: ArgsValue childComplexity: number } export type QueryComplexityEstimator = ( options: QueryComplexityEstimatorArgs ) => number | void export type QueryComplexity = | number | QueryComplexityEstimator export const queryComplexityPlugin = () => { return plugin({ name: 'query-complexity', description: ` The query complexity plugin allows defining field-level complexity values that works with the graphql-query-complexity library. `, fieldDefTypes, onCreateFieldResolver(config) { // Look for complexity property defined in the nexus config const complexity = config.fieldConfig.extensions?.nexus?.config.complexity // Skip if field doesn't have complexity property if (complexity == null) { return } // If the complexity is not a number or a function that returns a number, provide a warning if (typeof complexity !== 'number' && typeof complexity !== 'function') { const parentName = config.parentTypeConfig.name const fieldName = config.fieldConfig.extensions?.nexus?.config.name console.error( new Error( `The complexity property provided to ${parentName}.${fieldName} should be a number or a function that returns a number, saw ${typeof complexity}` ) ) return } // Mutate the field config's extensions property with new complexity field. // graphql-query-complexity will look for this property to estimate complexity config.fieldConfig.extensions = { ...config.fieldConfig.extensions, complexity, } as any return undefined }, }) }