UNPKG

@ardatan/relay-compiler

Version:

A compiler tool for building GraphQL-driven applications.

90 lines (79 loc) 2.71 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow strict-local * @format */ // flowlint ambiguous-object-type:error 'use strict'; const inferRootArgumentDefinitions = require('../core/inferRootArgumentDefinitions'); const { createUserError, eachWithCombinedError, } = require('../core/CompilerError'); import type CompilerContext from '../core/CompilerContext'; import type {ArgumentDefinition} from '../core/IR'; const SCHEMA_EXTENSION = 'directive @DEPRECATED__relay_ignore_unused_variables_error on QUERY | MUTATION | SUBSCRIPTION'; /** * Validates that there are no unused variables in the operation. * former `graphql-js`` NoUnusedVariablesRule */ function validateUnusedVariablesTransform( context: CompilerContext, ): CompilerContext { const contextWithUsedArguments = inferRootArgumentDefinitions(context); eachWithCombinedError(context.documents(), node => { if (node.kind !== 'Root') { return; } const rootArgumentLocations = new Map( node.argumentDefinitions.map(arg => [arg.name, arg.loc]), ); const nodeWithUsedArguments = contextWithUsedArguments.getRoot(node.name); const usedArguments = argumentDefinitionsToMap( nodeWithUsedArguments.argumentDefinitions, ); for (const usedArgumentName of usedArguments.keys()) { rootArgumentLocations.delete(usedArgumentName); } const ignoreErrorDirective = node.directives.find( ({name}) => name === 'DEPRECATED__relay_ignore_unused_variables_error', ); if (rootArgumentLocations.size > 0 && !ignoreErrorDirective) { const isPlural = rootArgumentLocations.size > 1; throw createUserError( `Variable${isPlural ? 's' : ''} '$${Array.from( rootArgumentLocations.keys(), ).join("', '$")}' ${isPlural ? 'are' : 'is'} never used in operation '${ node.name }'.`, Array.from(rootArgumentLocations.values()), ); } if (rootArgumentLocations.size === 0 && ignoreErrorDirective) { throw createUserError( "Invalid usage of '@DEPRECATED__relay_ignore_unused_variables_error.'" + `No unused variables found in the query '${node.name}'`, [ignoreErrorDirective.loc], ); } }); return context; } function argumentDefinitionsToMap<T: ArgumentDefinition>( argDefs: $ReadOnlyArray<T>, ): Map<string, T> { const map = new Map(); for (const argDef of argDefs) { map.set(argDef.name, argDef); } return map; } module.exports = { transform: validateUnusedVariablesTransform, SCHEMA_EXTENSION, };