From 5996cde9d9ccb62787aad0ae19ee9018e6436eb0 Mon Sep 17 00:00:00 2001 From: Sean Grove Date: Tue, 24 Nov 2020 16:57:21 -0800 Subject: [PATCH 1/2] Support more operation types, renaming, etc. --- src/Explorer.js | 64 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/Explorer.js b/src/Explorer.js index c2a8792..fdf2fb1 100644 --- a/src/Explorer.js +++ b/src/Explorer.js @@ -14,6 +14,7 @@ import * as React from 'react'; import { getNamedType, GraphQLObjectType, + GraphQLInterfaceType, isEnumType, isInputObjectType, isInterfaceType, @@ -1744,12 +1745,31 @@ class FieldView extends React.PureComponent< className += ' graphiql-explorer-deprecated'; } - const applicableFragments = + const availableInterfaceFragments = isObjectType(type) + ? type.getInterfaces().reduce((acc, next) => { + if (next.name !== type.name) { + return [ + ...acc, + ...((this.props.availableFragments || {})[next.name] || []), + ]; + } + + // Don't add these matches, since they'll be picked up by the simpler next check + return acc; + }, []) + : null; + + const basicApplicableFragments = isObjectType(type) || isInterfaceType(type) || isUnionType(type) ? this.props.availableFragments && this.props.availableFragments[type.name] : null; + const applicableFragments = [ + ...(basicApplicableFragments || []), + ...(availableInterfaceFragments || []), + ]; + const node = (
{ const containsMeaningfulSubselection = - isObjectType(type) && + (isObjectType(type) || isInterfaceType(type)) && selection && selection.selectionSet && selection.selectionSet.selections.filter( @@ -2427,26 +2447,37 @@ class Explorer extends React.PureComponent { : _relevantOperations; const renameOperation = (targetOperation, name) => { + const targetOperationExistingName = + (targetOperation.name && targetOperation.name.value) || 'unknown'; + const newName = name == null || name === '' ? null : {kind: 'Name', value: name, loc: undefined}; - const newOperation = {...targetOperation, name: newName}; - const existingDefs = parsedQuery.definitions; + const targetOperationIsFragment = + targetOperation.kind === 'FragmentDefinition'; - const newDefinitions = existingDefs.map(existingOperation => { - if (targetOperation === existingOperation) { - return newOperation; - } else { - return existingOperation; - } + return visit(parsedQuery, { + OperationDefinition: node => { + if (node.name.value === targetOperation.name.value) { + return {...node, name: newName}; + } + }, + FragmentDefinition: node => { + if (node.name.value === targetOperation.name.value) { + return {...node, name: newName}; + } + }, + FragmentSpread: node => { + if ( + targetOperationIsFragment && + node.name.value === targetOperationExistingName + ) { + return {...node, name: {...newName}}; + } + }, }); - - return { - ...parsedQuery, - definitions: newDefinitions, - }; }; const cloneOperation = ( @@ -2733,7 +2764,8 @@ class Explorer extends React.PureComponent { schema.getType(operation.typeCondition.name.value); const fragmentFields = - fragmentType instanceof GraphQLObjectType + fragmentType instanceof GraphQLObjectType || + fragmentType instanceof GraphQLInterfaceType ? fragmentType.getFields() : null; From 3810ac1d32c2f7eff92d5d44e2284bb781950eba Mon Sep 17 00:00:00 2001 From: Sean Grove Date: Tue, 1 Dec 2020 21:36:20 -0800 Subject: [PATCH 2/2] Better fragment renaming --- src/Explorer.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Explorer.js b/src/Explorer.js index fdf2fb1..d108d69 100644 --- a/src/Explorer.js +++ b/src/Explorer.js @@ -2460,12 +2460,20 @@ class Explorer extends React.PureComponent { return visit(parsedQuery, { OperationDefinition: node => { - if (node.name.value === targetOperation.name.value) { + if ( + !targetOperationIsFragment && + !!newName && + node?.name?.value === targetOperation?.name?.value + ) { return {...node, name: newName}; } }, FragmentDefinition: node => { - if (node.name.value === targetOperation.name.value) { + if ( + targetOperationIsFragment && + !!newName && + node?.name?.value === targetOperation?.name?.value + ) { return {...node, name: newName}; } },