From 418cf34b41ea32f308e9196127e3a118e3075305 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 7 May 2021 12:39:24 -0700 Subject: [PATCH 1/4] Unify InputValueConfig in schema definition Defines a central `GraphQLInputValueConfig` and `GraphQLInputValue` as well as single definitions for converting between them, unifying this common functionality between input values and arguments. This is a pre-req for #3049 --- src/index.d.ts | 4 + src/index.js | 4 + src/type/definition.d.ts | 59 ++++++--------- src/type/definition.js | 154 +++++++++++++++++---------------------- src/type/directives.d.ts | 26 ++++++- src/type/directives.js | 34 ++++++--- src/type/index.d.ts | 4 + src/type/index.js | 8 +- 8 files changed, 151 insertions(+), 142 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index ac935945c5..348ae20f1e 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -145,9 +145,13 @@ export { GraphQLSchemaExtensions, GraphQLDirectiveConfig, GraphQLDirectiveExtensions, + GraphQLDirectiveArgument, + GraphQLDirectiveArgumentConfig, GraphQLArgument, GraphQLArgumentConfig, GraphQLArgumentExtensions, + GraphQLInputValue, + GraphQLInputValueConfig, GraphQLEnumTypeConfig, GraphQLEnumTypeExtensions, GraphQLEnumValue, diff --git a/src/index.js b/src/index.js index 1e6b3f247a..4e64568ffb 100644 --- a/src/index.js +++ b/src/index.js @@ -144,6 +144,10 @@ export type { GraphQLDirectiveConfig, GraphQLArgument, GraphQLArgumentConfig, + GraphQLDirectiveArgument, + GraphQLDirectiveArgumentConfig, + GraphQLInputValue, + GraphQLInputValueConfig, GraphQLEnumTypeConfig, GraphQLEnumValue, GraphQLEnumValueConfig, diff --git a/src/type/definition.d.ts b/src/type/definition.d.ts index c520340b0e..d651b2e40a 100644 --- a/src/type/definition.d.ts +++ b/src/type/definition.d.ts @@ -441,10 +441,6 @@ export class GraphQLObjectType { get [Symbol.toStringTag](): string; } -export function argsToArgsConfig( - args: ReadonlyArray, -): GraphQLFieldConfigArgumentMap; - export interface GraphQLObjectTypeConfig { name: string; description?: Maybe; @@ -545,14 +541,7 @@ export interface GraphQLArgumentExtensions { [attributeName: string]: unknown; } -export interface GraphQLArgumentConfig { - description?: Maybe; - type: GraphQLInputType; - defaultValue?: unknown; - deprecationReason?: Maybe; - extensions?: Maybe>; - astNode?: Maybe; -} +export type GraphQLArgumentConfig = GraphQLInputValueConfig; export type GraphQLFieldConfigMap = ObjMap< GraphQLFieldConfig @@ -574,21 +563,32 @@ export interface GraphQLField< astNode?: Maybe; } -export interface GraphQLArgument { +export type GraphQLArgument = GraphQLInputValue; + +export function isRequiredArgument(arg: GraphQLArgument): boolean; + +export type GraphQLFieldMap = ObjMap< + GraphQLField +>; + +export interface GraphQLInputValue { name: string; description: Maybe; type: GraphQLInputType; defaultValue: unknown; deprecationReason: Maybe; - extensions: Maybe>; + extensions: Maybe>; astNode: Maybe; } -export function isRequiredArgument(arg: GraphQLArgument): boolean; - -export type GraphQLFieldMap = ObjMap< - GraphQLField ->; +export interface GraphQLInputValueConfig { + description?: Maybe; + type: GraphQLInputType; + defaultValue?: unknown; + deprecationReason?: Maybe; + extensions?: Maybe>; + astNode?: Maybe; +} /** * Custom extensions @@ -913,29 +913,14 @@ export interface GraphQLInputObjectTypeConfig { * an object which can contain all the values you need. */ export interface GraphQLInputFieldExtensions { - [attributeName: string]: any; + [attributeName: string]: unknown; } -export interface GraphQLInputFieldConfig { - description?: Maybe; - type: GraphQLInputType; - defaultValue?: unknown; - deprecationReason?: Maybe; - extensions?: Maybe>; - astNode?: Maybe; -} +export type GraphQLInputFieldConfig = GraphQLInputValueConfig; export type GraphQLInputFieldConfigMap = ObjMap; -export interface GraphQLInputField { - name: string; - description?: Maybe; - type: GraphQLInputType; - defaultValue?: unknown; - deprecationReason: Maybe; - extensions: Maybe>; - astNode?: Maybe; -} +export type GraphQLInputField = GraphQLInputValue; export function isRequiredInputField(field: GraphQLInputField): boolean; diff --git a/src/type/definition.js b/src/type/definition.js index 7abdc25b0a..7e2d00ecd1 100644 --- a/src/type/definition.js +++ b/src/type/definition.js @@ -821,7 +821,9 @@ function defineFieldMap( name: fieldName, description: fieldConfig.description, type: fieldConfig.type, - args: defineArguments(argsConfig), + args: Object.entries(argsConfig).map(([argName, argConfig]) => + defineInputValue(argConfig, argName), + ), resolve: fieldConfig.resolve, subscribe: fieldConfig.subscribe, deprecationReason: fieldConfig.deprecationReason, @@ -831,20 +833,6 @@ function defineFieldMap( }); } -export function defineArguments( - config: GraphQLFieldConfigArgumentMap, -): $ReadOnlyArray { - return Object.entries(config).map(([argName, argConfig]) => ({ - name: argName, - description: argConfig.description, - type: argConfig.type, - defaultValue: argConfig.defaultValue, - deprecationReason: argConfig.deprecationReason, - extensions: argConfig.extensions && toObjMap(argConfig.extensions), - astNode: argConfig.astNode, - })); -} - function isPlainObj(obj: mixed): boolean { return isObjectLike(obj) && !Array.isArray(obj); } @@ -855,7 +843,7 @@ function fieldsToFieldsConfig( return mapValue(fields, (field) => ({ description: field.description, type: field.type, - args: argsToArgsConfig(field.args), + args: keyValMap(field.args, (arg) => arg.name, inputValueToConfig), resolve: field.resolve, subscribe: field.subscribe, deprecationReason: field.deprecationReason, @@ -864,26 +852,6 @@ function fieldsToFieldsConfig( })); } -/** - * @internal - */ -export function argsToArgsConfig( - args: $ReadOnlyArray, -): GraphQLFieldConfigArgumentMap { - return keyValMap( - args, - (arg) => arg.name, - (arg) => ({ - description: arg.description, - type: arg.type, - defaultValue: arg.defaultValue, - deprecationReason: arg.deprecationReason, - extensions: arg.extensions, - astNode: arg.astNode, - }), - ); -} - export type GraphQLObjectTypeConfig = {| name: string, description?: ?string, @@ -960,14 +928,7 @@ export type GraphQLFieldConfig< export type GraphQLFieldConfigArgumentMap = ObjMap; -export type GraphQLArgumentConfig = {| - description?: ?string, - type: GraphQLInputType, - defaultValue?: mixed, - extensions?: ?ReadOnlyObjMapLike, - deprecationReason?: ?string, - astNode?: ?InputValueDefinitionNode, -|}; +export type GraphQLArgumentConfig = GraphQLInputValueConfig; export type GraphQLFieldConfigMap = ObjMap< GraphQLFieldConfig, @@ -989,7 +950,55 @@ export type GraphQLField< astNode: ?FieldDefinitionNode, |}; -export type GraphQLArgument = {| +export type GraphQLArgument = GraphQLInputValue; + +export function isRequiredArgument(arg: GraphQLArgument): boolean %checks { + return isNonNullType(arg.type) && arg.defaultValue === undefined; +} + +export type GraphQLFieldMap = ObjMap< + GraphQLField, +>; + +/** + * @internal + */ +export function defineInputValue( + config: GraphQLInputValueConfig, + name: string, +): GraphQLInputValue { + devAssert( + !('resolve' in config), + `${name} has a resolve property, but inputs cannot define resolvers.`, + ); + return { + name, + description: config.description, + type: config.type, + defaultValue: config.defaultValue, + deprecationReason: config.deprecationReason, + extensions: config.extensions && toObjMap(config.extensions), + astNode: config.astNode, + }; +} + +/** + * @internal + */ +export function inputValueToConfig( + inputValue: GraphQLInputValue, +): GraphQLInputValueConfig { + return { + description: inputValue.description, + type: inputValue.type, + defaultValue: inputValue.defaultValue, + deprecationReason: inputValue.deprecationReason, + extensions: inputValue.extensions, + astNode: inputValue.astNode, + }; +} + +export type GraphQLInputValue = {| name: string, description: ?string, type: GraphQLInputType, @@ -999,13 +1008,14 @@ export type GraphQLArgument = {| astNode: ?InputValueDefinitionNode, |}; -export function isRequiredArgument(arg: GraphQLArgument): boolean %checks { - return isNonNullType(arg.type) && arg.defaultValue === undefined; -} - -export type GraphQLFieldMap = ObjMap< - GraphQLField, ->; +export type GraphQLInputValueConfig = {| + description?: ?string, + type: GraphQLInputType, + defaultValue?: mixed, + deprecationReason?: ?string, + extensions?: ?ReadOnlyObjMapLike, + astNode?: ?InputValueDefinitionNode, +|}; /** * Interface Type Definition @@ -1497,18 +1507,10 @@ export class GraphQLInputObjectType { } toConfig(): GraphQLInputObjectTypeNormalizedConfig { - const fields = mapValue(this.getFields(), (field) => ({ - description: field.description, - type: field.type, - defaultValue: field.defaultValue, - extensions: field.extensions, - astNode: field.astNode, - })); - return { name: this.name, description: this.description, - fields, + fields: mapValue(this.getFields(), inputValueToConfig), extensions: this.extensions, astNode: this.astNode, extensionASTNodes: this.extensionASTNodes, @@ -1542,16 +1544,7 @@ function defineInputFieldMap( !('resolve' in fieldConfig), `${config.name}.${fieldName} field has a resolve property, but Input Types cannot define resolvers.`, ); - - return { - name: fieldName, - description: fieldConfig.description, - type: fieldConfig.type, - defaultValue: fieldConfig.defaultValue, - deprecationReason: fieldConfig.deprecationReason, - extensions: fieldConfig.extensions && toObjMap(fieldConfig.extensions), - astNode: fieldConfig.astNode, - }; + return defineInputValue(fieldConfig, fieldName); }); } @@ -1571,26 +1564,11 @@ type GraphQLInputObjectTypeNormalizedConfig = {| extensionASTNodes: $ReadOnlyArray, |}; -export type GraphQLInputFieldConfig = {| - description?: ?string, - type: GraphQLInputType, - defaultValue?: mixed, - deprecationReason?: ?string, - extensions?: ?ReadOnlyObjMapLike, - astNode?: ?InputValueDefinitionNode, -|}; +export type GraphQLInputFieldConfig = GraphQLInputValueConfig; export type GraphQLInputFieldConfigMap = ObjMap; -export type GraphQLInputField = {| - name: string, - description: ?string, - type: GraphQLInputType, - defaultValue: mixed, - deprecationReason: ?string, - extensions: ?ReadOnlyObjMap, - astNode: ?InputValueDefinitionNode, -|}; +export type GraphQLInputField = GraphQLInputValue; export function isRequiredInputField( field: GraphQLInputField, diff --git a/src/type/directives.d.ts b/src/type/directives.d.ts index 66415d879a..2ba312e853 100644 --- a/src/type/directives.d.ts +++ b/src/type/directives.d.ts @@ -2,11 +2,12 @@ /* eslint-disable import/no-cycle */ import { Maybe } from '../jsutils/Maybe'; +import { ObjMap } from '../jsutils/ObjMap'; import { DirectiveDefinitionNode } from '../language/ast'; import { DirectiveLocationEnum } from '../language/directiveLocation'; -import { GraphQLFieldConfigArgumentMap, GraphQLArgument } from './definition'; +import { GraphQLInputValue, GraphQLInputValueConfig } from './definition'; /** * Test if the given value is a GraphQL directive. @@ -36,14 +37,14 @@ export class GraphQLDirective { description: Maybe; locations: Array; isRepeatable: boolean; - args: Array; + args: Array; extensions: Maybe>; astNode: Maybe; constructor(config: Readonly); toConfig(): GraphQLDirectiveConfig & { - args: GraphQLFieldConfigArgumentMap; + args: ObjMap; isRepeatable: boolean; extensions: Maybe>; }; @@ -58,12 +59,29 @@ export interface GraphQLDirectiveConfig { name: string; description?: Maybe; locations: Array; - args?: Maybe; + args?: Maybe>; isRepeatable?: Maybe; extensions?: Maybe>; astNode?: Maybe; } +/** + * Custom extensions + * + * @remarks + * Use a unique identifier name for your extension, for example the name of + * your library or project. Do not use a shortened identifier as this increases + * the risk of conflicts. We recommend you add at most one extension field, + * an object which can contain all the values you need. + */ +export interface GraphQLDirectiveArgumentExtensions { + [attributeName: string]: unknown; +} + +export type GraphQLDirectiveArgument = GraphQLInputValue; + +export type GraphQLDirectiveArgumentConfig = GraphQLInputValueConfig; + /** * Used to conditionally include fields or fragments. */ diff --git a/src/type/directives.js b/src/type/directives.js index a6ca5005c9..cefb44ce22 100644 --- a/src/type/directives.js +++ b/src/type/directives.js @@ -1,5 +1,10 @@ -import type { ReadOnlyObjMap, ReadOnlyObjMapLike } from '../jsutils/ObjMap'; +import type { + ObjMap, + ReadOnlyObjMap, + ReadOnlyObjMapLike, +} from '../jsutils/ObjMap'; import { inspect } from '../jsutils/inspect'; +import { keyValMap } from '../jsutils/keyValMap'; import { toObjMap } from '../jsutils/toObjMap'; import { devAssert } from '../jsutils/devAssert'; import { instanceOf } from '../jsutils/instanceOf'; @@ -9,14 +14,11 @@ import type { DirectiveDefinitionNode } from '../language/ast'; import type { DirectiveLocationEnum } from '../language/directiveLocation'; import { DirectiveLocation } from '../language/directiveLocation'; -import type { - GraphQLArgument, - GraphQLFieldConfigArgumentMap, -} from './definition'; +import type { GraphQLInputValue, GraphQLInputValueConfig } from './definition'; import { GraphQLString, GraphQLBoolean } from './scalars'; import { - defineArguments, - argsToArgsConfig, + defineInputValue, + inputValueToConfig, GraphQLNonNull, } from './definition'; @@ -48,7 +50,7 @@ export class GraphQLDirective { name: string; description: ?string; locations: Array; - args: $ReadOnlyArray; + args: $ReadOnlyArray; isRepeatable: boolean; extensions: ?ReadOnlyObjMap; astNode: ?DirectiveDefinitionNode; @@ -73,7 +75,9 @@ export class GraphQLDirective { `@${config.name} args must be an object with argument names as keys.`, ); - this.args = defineArguments(args); + this.args = Object.entries(args).map(([argName, argConfig]) => + defineInputValue(argConfig, argName), + ); } toConfig(): GraphQLDirectiveNormalizedConfig { @@ -81,7 +85,7 @@ export class GraphQLDirective { name: this.name, description: this.description, locations: this.locations, - args: argsToArgsConfig(this.args), + args: keyValMap(this.args, (arg) => arg.name, inputValueToConfig), isRepeatable: this.isRepeatable, extensions: this.extensions, astNode: this.astNode, @@ -102,11 +106,13 @@ export class GraphQLDirective { } } +export type GraphQLDirectiveArgument = GraphQLInputValue; + export type GraphQLDirectiveConfig = {| name: string, description?: ?string, locations: Array, - args?: ?GraphQLFieldConfigArgumentMap, + args?: ?GraphQLDirectiveConfigArgumentMap, isRepeatable?: ?boolean, extensions?: ?ReadOnlyObjMapLike, astNode?: ?DirectiveDefinitionNode, @@ -114,11 +120,15 @@ export type GraphQLDirectiveConfig = {| type GraphQLDirectiveNormalizedConfig = {| ...GraphQLDirectiveConfig, - args: GraphQLFieldConfigArgumentMap, + args: GraphQLDirectiveConfigArgumentMap, isRepeatable: boolean, extensions: ?ReadOnlyObjMap, |}; +type GraphQLDirectiveConfigArgumentMap = ObjMap; + +export type GraphQLDirectiveArgumentConfig = GraphQLInputValueConfig; + /** * Used to conditionally include fields or fragments. */ diff --git a/src/type/index.d.ts b/src/type/index.d.ts index 253fcf2113..f645f4527a 100644 --- a/src/type/index.d.ts +++ b/src/type/index.d.ts @@ -80,6 +80,8 @@ export { GraphQLArgument, GraphQLArgumentConfig, GraphQLArgumentExtensions, + GraphQLInputValue, + GraphQLInputValueConfig, GraphQLEnumTypeConfig, GraphQLEnumTypeExtensions, GraphQLEnumValue, @@ -123,6 +125,7 @@ export { assertDirective, // Directives Definition GraphQLDirective, + GraphQLDirectiveArgument, // Built-in Directives defined by the Spec isSpecifiedDirective, specifiedDirectives, @@ -134,6 +137,7 @@ export { DEFAULT_DEPRECATION_REASON, // type GraphQLDirectiveConfig, + GraphQLDirectiveArgumentConfig, GraphQLDirectiveExtensions, } from './directives'; diff --git a/src/type/index.js b/src/type/index.js index bf0b17973e..3952381264 100644 --- a/src/type/index.js +++ b/src/type/index.js @@ -71,6 +71,7 @@ export { assertDirective, // Directives Definition GraphQLDirective, + GraphQLDirectiveArgument, // Built-in Directives defined by the Spec isSpecifiedDirective, specifiedDirectives, @@ -82,7 +83,10 @@ export { DEFAULT_DEPRECATION_REASON, } from './directives'; -export type { GraphQLDirectiveConfig } from './directives'; +export type { + GraphQLDirectiveConfig, + GraphQLDirectiveArgumentConfig, +} from './directives'; // Common built-in scalar instances. export { @@ -134,6 +138,8 @@ export type { ThunkObjMap, GraphQLArgument, GraphQLArgumentConfig, + GraphQLInputValue, + GraphQLInputValueConfig, GraphQLEnumTypeConfig, GraphQLEnumValue, GraphQLEnumValueConfig, From a44b1cf9f2e2e85c9daa1e3ff0d75dcb8b86b0a1 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Fri, 7 May 2021 13:03:15 -0700 Subject: [PATCH 2/4] Also add isRequiredInput() --- src/index.d.ts | 1 + src/index.js | 1 + src/type/__tests__/predicate-test.js | 27 +++++++++---------- src/type/definition.d.ts | 2 ++ src/type/definition.js | 14 +++++----- src/type/index.d.ts | 1 + src/type/index.js | 1 + src/type/validate.js | 11 ++++---- src/utilities/findBreakingChanges.js | 9 +++---- .../rules/ProvidedRequiredArgumentsRule.js | 10 +++---- .../rules/ValuesOfCorrectTypeRule.js | 4 +-- 11 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 348ae20f1e..123415ba46 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -94,6 +94,7 @@ export { isWrappingType, isNullableType, isNamedType, + isRequiredInput, isRequiredArgument, isRequiredInputField, isSpecifiedScalarType, diff --git a/src/index.js b/src/index.js index 4e64568ffb..d0fce51a1d 100644 --- a/src/index.js +++ b/src/index.js @@ -93,6 +93,7 @@ export { isWrappingType, isNullableType, isNamedType, + isRequiredInput, isRequiredArgument, isRequiredInputField, isSpecifiedScalarType, diff --git a/src/type/__tests__/predicate-test.js b/src/type/__tests__/predicate-test.js index f94bed1030..899752864c 100644 --- a/src/type/__tests__/predicate-test.js +++ b/src/type/__tests__/predicate-test.js @@ -49,8 +49,7 @@ import { isWrappingType, isNullableType, isNamedType, - isRequiredArgument, - isRequiredInputField, + isRequiredInput, assertType, assertScalarType, assertObjectType, @@ -562,7 +561,7 @@ describe('Type predicates', () => { }); }); - describe('isRequiredArgument', () => { + describe('isRequiredInput', () => { function buildArg(config: {| type: GraphQLInputType, defaultValue?: mixed, @@ -582,35 +581,33 @@ describe('Type predicates', () => { const requiredArg = buildArg({ type: new GraphQLNonNull(GraphQLString), }); - expect(isRequiredArgument(requiredArg)).to.equal(true); + expect(isRequiredInput(requiredArg)).to.equal(true); }); it('returns false for optional arguments', () => { const optArg1 = buildArg({ type: GraphQLString, }); - expect(isRequiredArgument(optArg1)).to.equal(false); + expect(isRequiredInput(optArg1)).to.equal(false); const optArg2 = buildArg({ type: GraphQLString, defaultValue: null, }); - expect(isRequiredArgument(optArg2)).to.equal(false); + expect(isRequiredInput(optArg2)).to.equal(false); const optArg3 = buildArg({ type: new GraphQLList(new GraphQLNonNull(GraphQLString)), }); - expect(isRequiredArgument(optArg3)).to.equal(false); + expect(isRequiredInput(optArg3)).to.equal(false); const optArg4 = buildArg({ type: new GraphQLNonNull(GraphQLString), defaultValue: 'default', }); - expect(isRequiredArgument(optArg4)).to.equal(false); + expect(isRequiredInput(optArg4)).to.equal(false); }); - }); - describe('isRequiredInputField', () => { function buildInputField(config: {| type: GraphQLInputType, defaultValue?: mixed, @@ -630,31 +627,31 @@ describe('Type predicates', () => { const requiredField = buildInputField({ type: new GraphQLNonNull(GraphQLString), }); - expect(isRequiredInputField(requiredField)).to.equal(true); + expect(isRequiredInput(requiredField)).to.equal(true); }); it('returns false for optional input field', () => { const optField1 = buildInputField({ type: GraphQLString, }); - expect(isRequiredInputField(optField1)).to.equal(false); + expect(isRequiredInput(optField1)).to.equal(false); const optField2 = buildInputField({ type: GraphQLString, defaultValue: null, }); - expect(isRequiredInputField(optField2)).to.equal(false); + expect(isRequiredInput(optField2)).to.equal(false); const optField3 = buildInputField({ type: new GraphQLList(new GraphQLNonNull(GraphQLString)), }); - expect(isRequiredInputField(optField3)).to.equal(false); + expect(isRequiredInput(optField3)).to.equal(false); const optField4 = buildInputField({ type: new GraphQLNonNull(GraphQLString), defaultValue: 'default', }); - expect(isRequiredInputField(optField4)).to.equal(false); + expect(isRequiredInput(optField4)).to.equal(false); }); }); }); diff --git a/src/type/definition.d.ts b/src/type/definition.d.ts index d651b2e40a..3614db5b1b 100644 --- a/src/type/definition.d.ts +++ b/src/type/definition.d.ts @@ -571,6 +571,8 @@ export type GraphQLFieldMap = ObjMap< GraphQLField >; +export function isRequiredInput(input: GraphQLInputValue): boolean; + export interface GraphQLInputValue { name: string; description: Maybe; diff --git a/src/type/definition.js b/src/type/definition.js index 7e2d00ecd1..8a7f0a72b1 100644 --- a/src/type/definition.js +++ b/src/type/definition.js @@ -952,14 +952,16 @@ export type GraphQLField< export type GraphQLArgument = GraphQLInputValue; -export function isRequiredArgument(arg: GraphQLArgument): boolean %checks { - return isNonNullType(arg.type) && arg.defaultValue === undefined; -} +export const isRequiredArgument = isRequiredInput; export type GraphQLFieldMap = ObjMap< GraphQLField, >; +export function isRequiredInput(input: GraphQLInputValue): boolean %checks { + return isNonNullType(input.type) && input.defaultValue === undefined; +} + /** * @internal */ @@ -1570,10 +1572,6 @@ export type GraphQLInputFieldConfigMap = ObjMap; export type GraphQLInputField = GraphQLInputValue; -export function isRequiredInputField( - field: GraphQLInputField, -): boolean %checks { - return isNonNullType(field.type) && field.defaultValue === undefined; -} +export const isRequiredInputField = isRequiredInput; export type GraphQLInputFieldMap = ObjMap; diff --git a/src/type/index.d.ts b/src/type/index.d.ts index f645f4527a..f6f1acf3d5 100644 --- a/src/type/index.d.ts +++ b/src/type/index.d.ts @@ -30,6 +30,7 @@ export { isWrappingType, isNullableType, isNamedType, + isRequiredInput, isRequiredArgument, isRequiredInputField, // Assertions diff --git a/src/type/index.js b/src/type/index.js index 3952381264..0545fb2c35 100644 --- a/src/type/index.js +++ b/src/type/index.js @@ -29,6 +29,7 @@ export { isWrappingType, isNullableType, isNamedType, + isRequiredInput, isRequiredArgument, isRequiredInputField, // Assertions diff --git a/src/type/validate.js b/src/type/validate.js index 919e58248d..ded614c6d6 100644 --- a/src/type/validate.js +++ b/src/type/validate.js @@ -34,8 +34,7 @@ import { isNonNullType, isInputType, isOutputType, - isRequiredArgument, - isRequiredInputField, + isRequiredInput, } from './definition'; /** @@ -180,7 +179,7 @@ function validateDirectives(context: SchemaValidationContext): void { ); } - if (isRequiredArgument(arg) && arg.deprecationReason != null) { + if (isRequiredInput(arg) && arg.deprecationReason != null) { context.reportError( `Required argument @${directive.name}(${arg.name}:) cannot be deprecated.`, [getDeprecatedDirectiveNode(arg.astNode), arg.astNode?.type], @@ -292,7 +291,7 @@ function validateFields( ); } - if (isRequiredArgument(arg) && arg.deprecationReason != null) { + if (isRequiredInput(arg) && arg.deprecationReason != null) { context.reportError( `Required argument ${type.name}.${field.name}(${argName}:) cannot be deprecated.`, [getDeprecatedDirectiveNode(arg.astNode), arg.astNode?.type], @@ -411,7 +410,7 @@ function validateTypeImplementsInterface( for (const typeArg of typeField.args) { const argName = typeArg.name; const ifaceArg = ifaceField.args.find((arg) => arg.name === argName); - if (!ifaceArg && isRequiredArgument(typeArg)) { + if (!ifaceArg && isRequiredInput(typeArg)) { context.reportError( `Object field ${type.name}.${fieldName} includes required argument ${argName} that is missing from the Interface field ${iface.name}.${fieldName}.`, [typeArg.astNode, ifaceField.astNode], @@ -529,7 +528,7 @@ function validateInputFields( ); } - if (isRequiredInputField(field) && field.deprecationReason != null) { + if (isRequiredInput(field) && field.deprecationReason != null) { context.reportError( `Required input field ${inputObj.name}.${field.name} cannot be deprecated.`, [ diff --git a/src/utilities/findBreakingChanges.js b/src/utilities/findBreakingChanges.js index d259d3b510..cc7ffe7443 100644 --- a/src/utilities/findBreakingChanges.js +++ b/src/utilities/findBreakingChanges.js @@ -29,8 +29,7 @@ import { isNonNullType, isListType, isNamedType, - isRequiredArgument, - isRequiredInputField, + isRequiredInput, } from '../type/definition'; import { astFromValue } from './astFromValue'; @@ -133,7 +132,7 @@ function findDirectiveChanges( const argsDiff = diff(oldDirective.args, newDirective.args); for (const newArg of argsDiff.added) { - if (isRequiredArgument(newArg)) { + if (isRequiredInput(newArg)) { schemaChanges.push({ type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED, description: `A required arg ${newArg.name} on directive ${oldDirective.name} was added.`, @@ -229,7 +228,7 @@ function findInputObjectTypeChanges( ); for (const newField of fieldsDiff.added) { - if (isRequiredInputField(newField)) { + if (isRequiredInput(newField)) { schemaChanges.push({ type: BreakingChangeType.REQUIRED_INPUT_FIELD_ADDED, description: `A required field ${newField.name} on input type ${oldType.name} was added.`, @@ -427,7 +426,7 @@ function findArgChanges( } for (const newArg of argsDiff.added) { - if (isRequiredArgument(newArg)) { + if (isRequiredInput(newArg)) { schemaChanges.push({ type: BreakingChangeType.REQUIRED_ARG_ADDED, description: `A required arg ${newArg.name} on ${oldType.name}.${oldField.name} was added.`, diff --git a/src/validation/rules/ProvidedRequiredArgumentsRule.js b/src/validation/rules/ProvidedRequiredArgumentsRule.js index 0ddc8f784d..d67443d104 100644 --- a/src/validation/rules/ProvidedRequiredArgumentsRule.js +++ b/src/validation/rules/ProvidedRequiredArgumentsRule.js @@ -9,7 +9,7 @@ import { Kind } from '../../language/kinds'; import { print } from '../../language/printer'; import { specifiedDirectives } from '../../type/directives'; -import { isType, isRequiredArgument } from '../../type/definition'; +import { isType, isRequiredInput } from '../../type/definition'; import type { ValidationContext, @@ -41,7 +41,7 @@ export function ProvidedRequiredArgumentsRule( fieldNode.arguments?.map((arg) => arg.name.value), ); for (const argDef of fieldDef.args) { - if (!providedArgs.has(argDef.name) && isRequiredArgument(argDef)) { + if (!providedArgs.has(argDef.name) && isRequiredInput(argDef)) { const argTypeStr = inspect(argDef.type); context.reportError( new GraphQLError( @@ -68,7 +68,7 @@ export function ProvidedRequiredArgumentsOnDirectivesRule( const definedDirectives = schema?.getDirectives() ?? specifiedDirectives; for (const directive of definedDirectives) { requiredArgsMap[directive.name] = keyMap( - directive.args.filter(isRequiredArgument), + directive.args.filter(isRequiredInput), (arg) => arg.name, ); } @@ -80,7 +80,7 @@ export function ProvidedRequiredArgumentsOnDirectivesRule( const argNodes = def.arguments ?? []; requiredArgsMap[def.name.value] = keyMap( - argNodes.filter(isRequiredArgumentNode), + argNodes.filter(isRequiredInputNode), (arg) => arg.name.value, ); } @@ -115,6 +115,6 @@ export function ProvidedRequiredArgumentsOnDirectivesRule( }; } -function isRequiredArgumentNode(arg: InputValueDefinitionNode): boolean { +function isRequiredInputNode(arg: InputValueDefinitionNode): boolean { return arg.type.kind === Kind.NON_NULL_TYPE && arg.defaultValue == null; } diff --git a/src/validation/rules/ValuesOfCorrectTypeRule.js b/src/validation/rules/ValuesOfCorrectTypeRule.js index 6d5dc5c1ca..9153b1a5ed 100644 --- a/src/validation/rules/ValuesOfCorrectTypeRule.js +++ b/src/validation/rules/ValuesOfCorrectTypeRule.js @@ -14,7 +14,7 @@ import { isInputObjectType, isListType, isNonNullType, - isRequiredInputField, + isRequiredInput, getNullableType, getNamedType, } from '../../type/definition'; @@ -50,7 +50,7 @@ export function ValuesOfCorrectTypeRule( const fieldNodeMap = keyMap(node.fields, (field) => field.name.value); for (const fieldDef of Object.values(type.getFields())) { const fieldNode = fieldNodeMap[fieldDef.name]; - if (!fieldNode && isRequiredInputField(fieldDef)) { + if (!fieldNode && isRequiredInput(fieldDef)) { const typeStr = inspect(fieldDef.type); context.reportError( new GraphQLError( From 452e3e022c6e3cd52c2677fe420b0111dfe4d188 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Mon, 10 May 2021 09:54:51 -0700 Subject: [PATCH 3/4] Revert DirectiveArgument --- src/index.d.ts | 2 -- src/index.js | 2 -- src/type/directives.d.ts | 25 ++++--------------------- src/type/directives.js | 14 ++++---------- src/type/index.d.ts | 2 -- src/type/index.js | 6 +----- 6 files changed, 9 insertions(+), 42 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 123415ba46..ddf092347f 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -146,8 +146,6 @@ export { GraphQLSchemaExtensions, GraphQLDirectiveConfig, GraphQLDirectiveExtensions, - GraphQLDirectiveArgument, - GraphQLDirectiveArgumentConfig, GraphQLArgument, GraphQLArgumentConfig, GraphQLArgumentExtensions, diff --git a/src/index.js b/src/index.js index d0fce51a1d..a9864a384f 100644 --- a/src/index.js +++ b/src/index.js @@ -145,8 +145,6 @@ export type { GraphQLDirectiveConfig, GraphQLArgument, GraphQLArgumentConfig, - GraphQLDirectiveArgument, - GraphQLDirectiveArgumentConfig, GraphQLInputValue, GraphQLInputValueConfig, GraphQLEnumTypeConfig, diff --git a/src/type/directives.d.ts b/src/type/directives.d.ts index 2ba312e853..69f8656335 100644 --- a/src/type/directives.d.ts +++ b/src/type/directives.d.ts @@ -7,7 +7,7 @@ import { ObjMap } from '../jsutils/ObjMap'; import { DirectiveDefinitionNode } from '../language/ast'; import { DirectiveLocationEnum } from '../language/directiveLocation'; -import { GraphQLInputValue, GraphQLInputValueConfig } from './definition'; +import { GraphQLArgument, GraphQLArgumentConfig } from './definition'; /** * Test if the given value is a GraphQL directive. @@ -37,14 +37,14 @@ export class GraphQLDirective { description: Maybe; locations: Array; isRepeatable: boolean; - args: Array; + args: Array; extensions: Maybe>; astNode: Maybe; constructor(config: Readonly); toConfig(): GraphQLDirectiveConfig & { - args: ObjMap; + args: ObjMap; isRepeatable: boolean; extensions: Maybe>; }; @@ -59,29 +59,12 @@ export interface GraphQLDirectiveConfig { name: string; description?: Maybe; locations: Array; - args?: Maybe>; + args?: Maybe>; isRepeatable?: Maybe; extensions?: Maybe>; astNode?: Maybe; } -/** - * Custom extensions - * - * @remarks - * Use a unique identifier name for your extension, for example the name of - * your library or project. Do not use a shortened identifier as this increases - * the risk of conflicts. We recommend you add at most one extension field, - * an object which can contain all the values you need. - */ -export interface GraphQLDirectiveArgumentExtensions { - [attributeName: string]: unknown; -} - -export type GraphQLDirectiveArgument = GraphQLInputValue; - -export type GraphQLDirectiveArgumentConfig = GraphQLInputValueConfig; - /** * Used to conditionally include fields or fragments. */ diff --git a/src/type/directives.js b/src/type/directives.js index cefb44ce22..702abebb1e 100644 --- a/src/type/directives.js +++ b/src/type/directives.js @@ -14,7 +14,7 @@ import type { DirectiveDefinitionNode } from '../language/ast'; import type { DirectiveLocationEnum } from '../language/directiveLocation'; import { DirectiveLocation } from '../language/directiveLocation'; -import type { GraphQLInputValue, GraphQLInputValueConfig } from './definition'; +import type { GraphQLArgument, GraphQLArgumentConfig } from './definition'; import { GraphQLString, GraphQLBoolean } from './scalars'; import { defineInputValue, @@ -50,7 +50,7 @@ export class GraphQLDirective { name: string; description: ?string; locations: Array; - args: $ReadOnlyArray; + args: $ReadOnlyArray; isRepeatable: boolean; extensions: ?ReadOnlyObjMap; astNode: ?DirectiveDefinitionNode; @@ -106,13 +106,11 @@ export class GraphQLDirective { } } -export type GraphQLDirectiveArgument = GraphQLInputValue; - export type GraphQLDirectiveConfig = {| name: string, description?: ?string, locations: Array, - args?: ?GraphQLDirectiveConfigArgumentMap, + args?: ?ObjMap, isRepeatable?: ?boolean, extensions?: ?ReadOnlyObjMapLike, astNode?: ?DirectiveDefinitionNode, @@ -120,15 +118,11 @@ export type GraphQLDirectiveConfig = {| type GraphQLDirectiveNormalizedConfig = {| ...GraphQLDirectiveConfig, - args: GraphQLDirectiveConfigArgumentMap, + args: ObjMap, isRepeatable: boolean, extensions: ?ReadOnlyObjMap, |}; -type GraphQLDirectiveConfigArgumentMap = ObjMap; - -export type GraphQLDirectiveArgumentConfig = GraphQLInputValueConfig; - /** * Used to conditionally include fields or fragments. */ diff --git a/src/type/index.d.ts b/src/type/index.d.ts index f6f1acf3d5..fc7c22ead8 100644 --- a/src/type/index.d.ts +++ b/src/type/index.d.ts @@ -126,7 +126,6 @@ export { assertDirective, // Directives Definition GraphQLDirective, - GraphQLDirectiveArgument, // Built-in Directives defined by the Spec isSpecifiedDirective, specifiedDirectives, @@ -138,7 +137,6 @@ export { DEFAULT_DEPRECATION_REASON, // type GraphQLDirectiveConfig, - GraphQLDirectiveArgumentConfig, GraphQLDirectiveExtensions, } from './directives'; diff --git a/src/type/index.js b/src/type/index.js index 0545fb2c35..851d9a192d 100644 --- a/src/type/index.js +++ b/src/type/index.js @@ -72,7 +72,6 @@ export { assertDirective, // Directives Definition GraphQLDirective, - GraphQLDirectiveArgument, // Built-in Directives defined by the Spec isSpecifiedDirective, specifiedDirectives, @@ -84,10 +83,7 @@ export { DEFAULT_DEPRECATION_REASON, } from './directives'; -export type { - GraphQLDirectiveConfig, - GraphQLDirectiveArgumentConfig, -} from './directives'; +export type { GraphQLDirectiveConfig } from './directives'; // Common built-in scalar instances. export { From 9830fdabee232309d3ffb1423f616048b3a4f6e9 Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Mon, 10 May 2021 10:27:14 -0700 Subject: [PATCH 4/4] Update other duplicated callsites in extendSchema and lexicographicSortSchema --- src/index.d.ts | 2 - src/index.js | 2 - src/type/definition.d.ts | 8 +--- src/type/definition.js | 8 +--- src/type/index.d.ts | 2 - src/type/index.js | 2 - src/utilities/extendSchema.js | 56 +++++++++--------------- src/utilities/lexicographicSortSchema.js | 24 ++++------ 8 files changed, 32 insertions(+), 72 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index ddf092347f..317602293e 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -160,14 +160,12 @@ export { GraphQLField, GraphQLFieldConfig, GraphQLFieldExtensions, - GraphQLFieldConfigArgumentMap, GraphQLFieldConfigMap, GraphQLFieldMap, GraphQLFieldResolver, GraphQLInputField, GraphQLInputFieldConfig, GraphQLInputFieldExtensions, - GraphQLInputFieldConfigMap, GraphQLInputFieldMap, GraphQLInputObjectTypeConfig, GraphQLInputObjectTypeExtensions, diff --git a/src/index.js b/src/index.js index a9864a384f..b46f10cd3a 100644 --- a/src/index.js +++ b/src/index.js @@ -153,13 +153,11 @@ export type { GraphQLEnumValueConfigMap, GraphQLField, GraphQLFieldConfig, - GraphQLFieldConfigArgumentMap, GraphQLFieldConfigMap, GraphQLFieldMap, GraphQLFieldResolver, GraphQLInputField, GraphQLInputFieldConfig, - GraphQLInputFieldConfigMap, GraphQLInputFieldMap, GraphQLInputObjectTypeConfig, GraphQLInterfaceTypeConfig, diff --git a/src/type/definition.d.ts b/src/type/definition.d.ts index 3614db5b1b..f07202d91a 100644 --- a/src/type/definition.d.ts +++ b/src/type/definition.d.ts @@ -516,7 +516,7 @@ export interface GraphQLFieldConfig< > { description?: Maybe; type: GraphQLOutputType; - args?: GraphQLFieldConfigArgumentMap; + args?: ObjMap; resolve?: GraphQLFieldResolver; subscribe?: GraphQLFieldResolver; deprecationReason?: Maybe; @@ -526,8 +526,6 @@ export interface GraphQLFieldConfig< astNode?: Maybe; } -export type GraphQLFieldConfigArgumentMap = ObjMap; - /** * Custom extensions * @@ -885,7 +883,7 @@ export class GraphQLInputObjectType { getFields(): GraphQLInputFieldMap; toConfig(): GraphQLInputObjectTypeConfig & { - fields: GraphQLInputFieldConfigMap; + fields: ObjMap; extensions: Maybe>; extensionASTNodes: ReadonlyArray; }; @@ -920,8 +918,6 @@ export interface GraphQLInputFieldExtensions { export type GraphQLInputFieldConfig = GraphQLInputValueConfig; -export type GraphQLInputFieldConfigMap = ObjMap; - export type GraphQLInputField = GraphQLInputValue; export function isRequiredInputField(field: GraphQLInputField): boolean; diff --git a/src/type/definition.js b/src/type/definition.js index 8a7f0a72b1..c16433d5b3 100644 --- a/src/type/definition.js +++ b/src/type/definition.js @@ -918,7 +918,7 @@ export type GraphQLFieldConfig< > = {| description?: ?string, type: GraphQLOutputType, - args?: GraphQLFieldConfigArgumentMap, + args?: ObjMap, resolve?: GraphQLFieldResolver, subscribe?: GraphQLFieldResolver, deprecationReason?: ?string, @@ -926,8 +926,6 @@ export type GraphQLFieldConfig< astNode?: ?FieldDefinitionNode, |}; -export type GraphQLFieldConfigArgumentMap = ObjMap; - export type GraphQLArgumentConfig = GraphQLInputValueConfig; export type GraphQLFieldConfigMap = ObjMap< @@ -1561,15 +1559,13 @@ export type GraphQLInputObjectTypeConfig = {| type GraphQLInputObjectTypeNormalizedConfig = {| ...GraphQLInputObjectTypeConfig, - fields: GraphQLInputFieldConfigMap, + fields: ObjMap, extensions: ?ReadOnlyObjMap, extensionASTNodes: $ReadOnlyArray, |}; export type GraphQLInputFieldConfig = GraphQLInputValueConfig; -export type GraphQLInputFieldConfigMap = ObjMap; - export type GraphQLInputField = GraphQLInputValue; export const isRequiredInputField = isRequiredInput; diff --git a/src/type/index.d.ts b/src/type/index.d.ts index fc7c22ead8..365256dfd1 100644 --- a/src/type/index.d.ts +++ b/src/type/index.d.ts @@ -91,14 +91,12 @@ export { GraphQLEnumValueExtensions, GraphQLField, GraphQLFieldConfig, - GraphQLFieldConfigArgumentMap, GraphQLFieldConfigMap, GraphQLFieldExtensions, GraphQLFieldMap, GraphQLFieldResolver, GraphQLInputField, GraphQLInputFieldConfig, - GraphQLInputFieldConfigMap, GraphQLInputFieldExtensions, GraphQLInputFieldMap, GraphQLInputObjectTypeConfig, diff --git a/src/type/index.js b/src/type/index.js index 851d9a192d..6bf0943f22 100644 --- a/src/type/index.js +++ b/src/type/index.js @@ -143,13 +143,11 @@ export type { GraphQLEnumValueConfigMap, GraphQLField, GraphQLFieldConfig, - GraphQLFieldConfigArgumentMap, GraphQLFieldConfigMap, GraphQLFieldMap, GraphQLFieldResolver, GraphQLInputField, GraphQLInputFieldConfig, - GraphQLInputFieldConfigMap, GraphQLInputFieldMap, GraphQLInputObjectTypeConfig, GraphQLInterfaceTypeConfig, diff --git a/src/utilities/extendSchema.js b/src/utilities/extendSchema.js index 4aeac58584..9c55417d95 100644 --- a/src/utilities/extendSchema.js +++ b/src/utilities/extendSchema.js @@ -1,3 +1,4 @@ +import type { ObjMap } from '../jsutils/ObjMap'; import { keyMap } from '../jsutils/keyMap'; import { inspect } from '../jsutils/inspect'; import { mapValue } from '../jsutils/mapValue'; @@ -47,10 +48,9 @@ import type { GraphQLNamedType, GraphQLFieldConfig, GraphQLFieldConfigMap, + GraphQLInputValueConfig, GraphQLArgumentConfig, - GraphQLFieldConfigArgumentMap, GraphQLEnumValueConfigMap, - GraphQLInputFieldConfigMap, } from '../type/definition'; import { assertSchema, GraphQLSchema } from '../type/schema'; import { specifiedScalarTypes, isSpecifiedScalarType } from '../type/scalars'; @@ -444,7 +444,7 @@ export function extendSchemaImpl( // $FlowFixMe[incompatible-call] locations: node.locations.map(({ value }) => value), isRepeatable: node.repeatable, - args: buildArgumentMap(node.arguments), + args: buildInputValueMap(node.arguments), astNode: node, }); } @@ -469,7 +469,7 @@ export function extendSchemaImpl( // with validateSchema() will produce more actionable results. type: getWrappedType(field.type), description: field.description?.value, - args: buildArgumentMap(field.arguments), + args: buildInputValueMap(field.arguments), deprecationReason: getDeprecationReason(field), astNode: field, }; @@ -478,54 +478,38 @@ export function extendSchemaImpl( return fieldConfigMap; } - function buildArgumentMap( - args: ?$ReadOnlyArray, - ): GraphQLFieldConfigArgumentMap { + function buildInputValueMap( + nodes: ?$ReadOnlyArray, + configMap: ObjMap = Object.create(null), + ): ObjMap { // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') - const argsNodes = args ?? []; + const inputNodes = nodes ?? []; - const argConfigMap = Object.create(null); - for (const arg of argsNodes) { + for (const node of inputNodes) { // Note: While this could make assertions to get the correctly typed // value, that would throw immediately while type system validation // with validateSchema() will produce more actionable results. - const type: any = getWrappedType(arg.type); + const type: any = getWrappedType(node.type); - argConfigMap[arg.name.value] = { + configMap[node.name.value] = { type, - description: arg.description?.value, - defaultValue: valueFromAST(arg.defaultValue, type), - deprecationReason: getDeprecationReason(arg), - astNode: arg, + description: node.description?.value, + defaultValue: valueFromAST(node.defaultValue, type), + deprecationReason: getDeprecationReason(node), + astNode: node, }; } - return argConfigMap; + return configMap; } function buildInputFieldMap( nodes: $ReadOnlyArray< InputObjectTypeDefinitionNode | InputObjectTypeExtensionNode, >, - ): GraphQLInputFieldConfigMap { - const inputFieldMap = Object.create(null); + ): ObjMap { + let inputFieldMap = Object.create(null); for (const node of nodes) { - // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203') - const fieldsNodes = node.fields ?? []; - - for (const field of fieldsNodes) { - // Note: While this could make assertions to get the correctly typed - // value, that would throw immediately while type system validation - // with validateSchema() will produce more actionable results. - const type: any = getWrappedType(field.type); - - inputFieldMap[field.name.value] = { - type, - description: field.description?.value, - defaultValue: valueFromAST(field.defaultValue, type), - deprecationReason: getDeprecationReason(field), - astNode: field, - }; - } + inputFieldMap = buildInputValueMap(node.fields, inputFieldMap); } return inputFieldMap; } diff --git a/src/utilities/lexicographicSortSchema.js b/src/utilities/lexicographicSortSchema.js index 291248ec1a..03918ce344 100644 --- a/src/utilities/lexicographicSortSchema.js +++ b/src/utilities/lexicographicSortSchema.js @@ -8,8 +8,7 @@ import type { GraphQLType, GraphQLNamedType, GraphQLFieldConfigMap, - GraphQLFieldConfigArgumentMap, - GraphQLInputFieldConfigMap, + GraphQLInputValueConfig, } from '../type/definition'; import { GraphQLSchema } from '../type/schema'; import { GraphQLDirective } from '../type/directives'; @@ -79,14 +78,14 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { return new GraphQLDirective({ ...config, locations: sortBy(config.locations, (x) => x), - args: sortArgs(config.args), + args: sortInputs(config.args), }); } - function sortArgs(args: GraphQLFieldConfigArgumentMap) { - return sortObjMap(args, (arg) => ({ - ...arg, - type: replaceType(arg.type), + function sortInputs(inputs: ObjMap) { + return sortObjMap(inputs, (input) => ({ + ...input, + type: replaceType(input.type), })); } @@ -94,14 +93,7 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { return sortObjMap(fieldsMap, (field) => ({ ...field, type: replaceType(field.type), - args: sortArgs(field.args), - })); - } - - function sortInputFields(fieldsMap: GraphQLInputFieldConfigMap) { - return sortObjMap(fieldsMap, (field) => ({ - ...field, - type: replaceType(field.type), + args: sortInputs(field.args), })); } @@ -148,7 +140,7 @@ export function lexicographicSortSchema(schema: GraphQLSchema): GraphQLSchema { const config = type.toConfig(); return new GraphQLInputObjectType({ ...config, - fields: () => sortInputFields(config.fields), + fields: () => sortInputs(config.fields), }); }