diff --git a/src/execution/__tests__/nonnull-test.ts b/src/execution/__tests__/nonnull-test.ts
index 12b223a622d..9563b844085 100644
--- a/src/execution/__tests__/nonnull-test.ts
+++ b/src/execution/__tests__/nonnull-test.ts
@@ -620,7 +620,7 @@ describe('Execute: handles non-nullable types', () => {
errors: [
{
message:
- 'Argument "cannotBeNull" of required type "String!" was not provided.',
+ 'Argument Query.withNonNullArg(cannotBeNull:) of required type String! was not provided.',
locations: [{ line: 3, column: 13 }],
path: ['withNonNullArg'],
},
@@ -647,7 +647,7 @@ describe('Execute: handles non-nullable types', () => {
errors: [
{
message:
- 'Argument "cannotBeNull" of non-null type "String!" must not be null.',
+ 'Argument Query.withNonNullArg(cannotBeNull:) of non-null type String! must not be null.',
locations: [{ line: 3, column: 42 }],
path: ['withNonNullArg'],
},
@@ -677,7 +677,7 @@ describe('Execute: handles non-nullable types', () => {
errors: [
{
message:
- 'Argument "cannotBeNull" of required type "String!" was provided the variable "$testVar" which was not provided a runtime value.',
+ 'Argument Query.withNonNullArg(cannotBeNull:) of required type String! was provided the variable "$testVar" which was not provided a runtime value.',
locations: [{ line: 3, column: 42 }],
path: ['withNonNullArg'],
},
@@ -705,7 +705,7 @@ describe('Execute: handles non-nullable types', () => {
errors: [
{
message:
- 'Argument "cannotBeNull" of non-null type "String!" must not be null.',
+ 'Argument Query.withNonNullArg(cannotBeNull:) of non-null type String! must not be null.',
locations: [{ line: 3, column: 43 }],
path: ['withNonNullArg'],
},
diff --git a/src/execution/__tests__/oneof-test.ts b/src/execution/__tests__/oneof-test.ts
index af0e0580abf..432045d50e6 100644
--- a/src/execution/__tests__/oneof-test.ts
+++ b/src/execution/__tests__/oneof-test.ts
@@ -83,7 +83,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
message:
// This type of error would be caught at validation-time
// hence the vague error message here.
- 'Argument "input" of non-null type "TestInputObject!" must not be null.',
+ 'Argument Query.test(input:) of non-null type TestInputObject! must not be null.',
path: ['test'],
},
],
diff --git a/src/execution/__tests__/variables-test.ts b/src/execution/__tests__/variables-test.ts
index 6e4b39e8101..9cea44a1d2e 100644
--- a/src/execution/__tests__/variables-test.ts
+++ b/src/execution/__tests__/variables-test.ts
@@ -226,7 +226,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Argument "input" has invalid value ["foo", "bar", "baz"].',
+ 'Argument TestType.fieldWithObjectInput(input:) of type TestInputObject has invalid value ["foo", "bar", "baz"].',
path: ['fieldWithObjectInput'],
locations: [{ line: 3, column: 41 }],
},
@@ -262,7 +262,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Argument "input" has invalid value { c: "foo", e: "bar" }.',
+ 'Argument TestType.fieldWithObjectInput(input:) of type TestInputObject has invalid value { c: "foo", e: "bar" }.',
path: ['fieldWithObjectInput'],
locations: [{ line: 3, column: 41 }],
},
@@ -678,7 +678,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Variable "$value" of required type "String!" was not provided.',
+ 'Variable "$value" of required type String! was not provided.',
locations: [{ line: 2, column: 16 }],
},
],
@@ -697,7 +697,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Variable "$value" of non-null type "String!" must not be null.',
+ 'Variable "$value" of non-null type String! must not be null.',
locations: [{ line: 2, column: 16 }],
},
],
@@ -743,7 +743,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Argument "input" of required type "String!" was not provided.',
+ 'Argument TestType.fieldWithNonNullableStringInput(input:) of required type String! was not provided.',
locations: [{ line: 1, column: 3 }],
path: ['fieldWithNonNullableStringInput'],
},
@@ -791,7 +791,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Argument "input" of required type "String!" was provided the variable "$foo" which was not provided a runtime value.',
+ 'Argument TestType.fieldWithNonNullableStringInput(input:) of required type String! was provided the variable "$foo" which was not provided a runtime value.',
locations: [{ line: 3, column: 50 }],
path: ['fieldWithNonNullableStringInput'],
},
@@ -846,7 +846,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Variable "$input" of non-null type "[String]!" must not be null.',
+ 'Variable "$input" of non-null type [String]! must not be null.',
locations: [{ line: 2, column: 16 }],
},
],
@@ -928,7 +928,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Variable "$input" of non-null type "[String!]!" must not be null.',
+ 'Variable "$input" of non-null type [String!]! must not be null.',
locations: [{ line: 2, column: 16 }],
},
],
@@ -977,7 +977,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Variable "$input" expected value of type "TestType!" which cannot be used as an input type.',
+ 'Variable "$input" expected value of type TestType! which cannot be used as an input type.',
locations: [{ line: 2, column: 24 }],
},
],
@@ -996,7 +996,7 @@ describe('Execute: Handles inputs', () => {
errors: [
{
message:
- 'Variable "$input" expected value of type "UnknownType!" which cannot be used as an input type.',
+ 'Variable "$input" expected value of type UnknownType! which cannot be used as an input type.',
locations: [{ line: 2, column: 24 }],
},
],
@@ -1042,7 +1042,8 @@ describe('Execute: Handles inputs', () => {
},
errors: [
{
- message: 'Argument "input" has invalid value WRONG_TYPE.',
+ message:
+ 'Argument TestType.fieldWithDefaultArgumentValue(input:) of type String has invalid value WRONG_TYPE.',
locations: [{ line: 3, column: 48 }],
path: ['fieldWithDefaultArgumentValue'],
},
diff --git a/src/execution/values.ts b/src/execution/values.ts
index 5511911c782..96bca78c95a 100644
--- a/src/execution/values.ts
+++ b/src/execution/values.ts
@@ -84,7 +84,7 @@ function coerceVariableValues(
const varTypeStr = print(varDefNode.type);
onError(
new GraphQLError(
- `Variable "$${varName}" expected value of type "${varTypeStr}" which cannot be used as an input type.`,
+ `Variable "$${varName}" expected value of type ${varTypeStr} which cannot be used as an input type.`,
{ nodes: varDefNode.type },
),
);
@@ -95,10 +95,9 @@ function coerceVariableValues(
if (varDefNode.defaultValue) {
coercedValues[varName] = valueFromAST(varDefNode.defaultValue, varType);
} else if (isNonNullType(varType)) {
- const varTypeStr = inspect(varType);
onError(
new GraphQLError(
- `Variable "$${varName}" of required type "${varTypeStr}" was not provided.`,
+ `Variable "$${varName}" of required type ${varType} was not provided.`,
{ nodes: varDefNode },
),
);
@@ -108,10 +107,9 @@ function coerceVariableValues(
const value = inputs[varName];
if (value === null && isNonNullType(varType)) {
- const varTypeStr = inspect(varType);
onError(
new GraphQLError(
- `Variable "$${varName}" of non-null type "${varTypeStr}" must not be null.`,
+ `Variable "$${varName}" of non-null type ${varType} must not be null.`,
{ nodes: varDefNode },
),
);
@@ -170,8 +168,7 @@ export function getArgumentValues(
coercedValues[name] = argDef.defaultValue;
} else if (isNonNullType(argType)) {
throw new GraphQLError(
- `Argument "${name}" of required type "${inspect(argType)}" ` +
- 'was not provided.',
+ `Argument ${argDef} of required type ${argType} was not provided.`,
{ nodes: node },
);
}
@@ -191,7 +188,7 @@ export function getArgumentValues(
coercedValues[name] = argDef.defaultValue;
} else if (isNonNullType(argType)) {
throw new GraphQLError(
- `Argument "${name}" of required type "${inspect(argType)}" ` +
+ `Argument ${argDef} of required type ${argType} ` +
`was provided the variable "$${variableName}" which was not provided a runtime value.`,
{ nodes: valueNode },
);
@@ -203,8 +200,7 @@ export function getArgumentValues(
if (isNull && isNonNullType(argType)) {
throw new GraphQLError(
- `Argument "${name}" of non-null type "${inspect(argType)}" ` +
- 'must not be null.',
+ `Argument ${argDef} of non-null type ${argType} must not be null.`,
{ nodes: valueNode },
);
}
@@ -215,7 +211,9 @@ export function getArgumentValues(
// execution. This is a runtime check to ensure execution does not
// continue with an invalid argument value.
throw new GraphQLError(
- `Argument "${name}" has invalid value ${print(valueNode)}.`,
+ `Argument ${argDef} of type ${argType} has invalid value ${print(
+ valueNode,
+ )}.`,
{ nodes: valueNode },
);
}
diff --git a/src/index.ts b/src/index.ts
index 44bbed4559d..ef6eda71fb9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -40,12 +40,17 @@ export {
// Definitions
GraphQLSchema,
GraphQLDirective,
+ GraphQLSchemaElement,
GraphQLScalarType,
GraphQLObjectType,
GraphQLInterfaceType,
GraphQLUnionType,
GraphQLEnumType,
GraphQLInputObjectType,
+ GraphQLField,
+ GraphQLArgument,
+ GraphQLEnumValue,
+ GraphQLInputField,
GraphQLList,
GraphQLNonNull,
// Standard GraphQL Scalars
@@ -161,23 +166,19 @@ export type {
GraphQLSchemaExtensions,
GraphQLDirectiveConfig,
GraphQLDirectiveExtensions,
- GraphQLArgument,
GraphQLArgumentConfig,
GraphQLArgumentExtensions,
GraphQLEnumTypeConfig,
GraphQLEnumTypeExtensions,
- GraphQLEnumValue,
GraphQLEnumValueConfig,
GraphQLEnumValueConfigMap,
GraphQLEnumValueExtensions,
- GraphQLField,
GraphQLFieldConfig,
GraphQLFieldConfigArgumentMap,
GraphQLFieldConfigMap,
GraphQLFieldExtensions,
GraphQLFieldMap,
GraphQLFieldResolver,
- GraphQLInputField,
GraphQLInputFieldConfig,
GraphQLInputFieldConfigMap,
GraphQLInputFieldExtensions,
diff --git a/src/type/__tests__/definition-test.ts b/src/type/__tests__/definition-test.ts
index 9a491fc31f5..e738a08818d 100644
--- a/src/type/__tests__/definition-test.ts
+++ b/src/type/__tests__/definition-test.ts
@@ -117,11 +117,11 @@ describe('Type System: Objects', () => {
},
};
const testObject1 = new GraphQLObjectType({
- name: 'Test1',
+ name: 'Test',
fields: outputFields,
});
const testObject2 = new GraphQLObjectType({
- name: 'Test2',
+ name: 'Test',
fields: outputFields,
});
@@ -143,11 +143,11 @@ describe('Type System: Objects', () => {
field2: { type: ScalarType },
};
const testInputObject1 = new GraphQLInputObjectType({
- name: 'Test1',
+ name: 'Test',
fields: inputFields,
});
const testInputObject2 = new GraphQLInputObjectType({
- name: 'Test2',
+ name: 'Test',
fields: inputFields,
});
@@ -193,18 +193,17 @@ describe('Type System: Objects', () => {
f: { type: ScalarType },
}),
});
- expect(objType.getFields()).to.deep.equal({
- f: {
- name: 'f',
- description: undefined,
- type: ScalarType,
- args: [],
- resolve: undefined,
- subscribe: undefined,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
+ expect(objType.getFields().f).to.deep.include({
+ coordinate: 'SomeObject.f',
+ name: 'f',
+ description: undefined,
+ type: ScalarType,
+ args: [],
+ resolve: undefined,
+ subscribe: undefined,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
});
});
@@ -220,28 +219,32 @@ describe('Type System: Objects', () => {
},
},
});
- expect(objType.getFields()).to.deep.equal({
- f: {
- name: 'f',
- description: undefined,
- type: ScalarType,
- args: [
- {
- name: 'arg',
- description: undefined,
- type: ScalarType,
- defaultValue: undefined,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- ],
- resolve: undefined,
- subscribe: undefined,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
+
+ const f = objType.getFields().f;
+
+ expect(f).to.deep.include({
+ coordinate: 'SomeObject.f',
+ name: 'f',
+ description: undefined,
+ type: ScalarType,
+ resolve: undefined,
+ subscribe: undefined,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
+
+ expect(f.args).to.have.lengthOf(1);
+
+ expect(f.args[0]).to.deep.include({
+ coordinate: 'SomeObject.f(arg:)',
+ name: 'arg',
+ description: undefined,
+ type: ScalarType,
+ defaultValue: undefined,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
});
});
@@ -432,32 +435,39 @@ describe('Type System: Enums', () => {
},
});
- expect(EnumTypeWithNullishValue.getValues()).to.deep.equal([
- {
- name: 'NULL',
- description: undefined,
- value: null,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- {
- name: 'NAN',
- description: undefined,
- value: NaN,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- {
- name: 'NO_CUSTOM_VALUE',
- description: undefined,
- value: 'NO_CUSTOM_VALUE',
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- ]);
+ const values = EnumTypeWithNullishValue.getValues();
+
+ expect(values).to.have.lengthOf(3);
+
+ expect(values[0]).to.deep.include({
+ coordinate: 'EnumWithNullishValue.NULL',
+ name: 'NULL',
+ description: undefined,
+ value: null,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
+
+ expect(values[1]).to.deep.include({
+ coordinate: 'EnumWithNullishValue.NAN',
+ name: 'NAN',
+ description: undefined,
+ value: NaN,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
+
+ expect(values[2]).to.deep.include({
+ coordinate: 'EnumWithNullishValue.NO_CUSTOM_VALUE',
+ name: 'NO_CUSTOM_VALUE',
+ description: undefined,
+ value: 'NO_CUSTOM_VALUE',
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
});
it('accepts a well defined Enum type with empty value definition', () => {
@@ -512,16 +522,15 @@ describe('Type System: Input Objects', () => {
f: { type: ScalarType },
},
});
- expect(inputObjType.getFields()).to.deep.equal({
- f: {
- name: 'f',
- description: undefined,
- type: ScalarType,
- defaultValue: undefined,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
+ expect(inputObjType.getFields().f).to.deep.include({
+ coordinate: 'SomeInputObject.f',
+ name: 'f',
+ description: undefined,
+ type: ScalarType,
+ defaultValue: undefined,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
});
});
@@ -532,16 +541,15 @@ describe('Type System: Input Objects', () => {
f: { type: ScalarType },
}),
});
- expect(inputObjType.getFields()).to.deep.equal({
- f: {
- name: 'f',
- description: undefined,
- type: ScalarType,
- defaultValue: undefined,
- extensions: {},
- deprecationReason: undefined,
- astNode: undefined,
- },
+ expect(inputObjType.getFields().f).to.deep.include({
+ coordinate: 'SomeInputObject.f',
+ name: 'f',
+ description: undefined,
+ type: ScalarType,
+ defaultValue: undefined,
+ extensions: {},
+ deprecationReason: undefined,
+ astNode: undefined,
});
});
diff --git a/src/type/__tests__/directive-test.ts b/src/type/__tests__/directive-test.ts
index 03af5e1fd96..9b9ca316958 100644
--- a/src/type/__tests__/directive-test.ts
+++ b/src/type/__tests__/directive-test.ts
@@ -33,29 +33,33 @@ describe('Type System: Directive', () => {
expect(directive).to.deep.include({
name: 'Foo',
- args: [
- {
- name: 'foo',
- description: undefined,
- type: GraphQLString,
- defaultValue: undefined,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- {
- name: 'bar',
- description: undefined,
- type: GraphQLInt,
- defaultValue: undefined,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- ],
isRepeatable: false,
locations: ['QUERY'],
});
+
+ expect(directive.args).to.have.lengthOf(2);
+
+ expect(directive.args[0]).to.deep.include({
+ coordinate: '@Foo(foo:)',
+ name: 'foo',
+ description: undefined,
+ type: GraphQLString,
+ defaultValue: undefined,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
+
+ expect(directive.args[1]).to.deep.include({
+ coordinate: '@Foo(bar:)',
+ name: 'bar',
+ description: undefined,
+ type: GraphQLInt,
+ defaultValue: undefined,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
});
it('defines a repeatable directive', () => {
diff --git a/src/type/__tests__/enumType-test.ts b/src/type/__tests__/enumType-test.ts
index f2786947c6d..49f937356b5 100644
--- a/src/type/__tests__/enumType-test.ts
+++ b/src/type/__tests__/enumType-test.ts
@@ -343,24 +343,28 @@ describe('Type System: Enum Values', () => {
it('presents a getValues() API for complex enums', () => {
const values = ComplexEnum.getValues();
- expect(values).to.have.deep.ordered.members([
- {
- name: 'ONE',
- description: undefined,
- value: Complex1,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- {
- name: 'TWO',
- description: undefined,
- value: Complex2,
- deprecationReason: undefined,
- extensions: {},
- astNode: undefined,
- },
- ]);
+
+ expect(values).to.have.lengthOf(2);
+
+ expect(values[0]).to.deep.include({
+ coordinate: 'Complex.ONE',
+ name: 'ONE',
+ description: undefined,
+ value: Complex1,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
+
+ expect(values[1]).to.deep.include({
+ coordinate: 'Complex.TWO',
+ name: 'TWO',
+ description: undefined,
+ value: Complex2,
+ deprecationReason: undefined,
+ extensions: {},
+ astNode: undefined,
+ });
});
it('presents a getValue() API for complex enums', () => {
diff --git a/src/type/__tests__/introspection-test.ts b/src/type/__tests__/introspection-test.ts
index e6e5d0943e1..97fb29dee05 100644
--- a/src/type/__tests__/introspection-test.ts
+++ b/src/type/__tests__/introspection-test.ts
@@ -1644,7 +1644,7 @@ describe('Introspection', () => {
errors: [
{
message:
- 'Field "__type" argument "name" of type "String!" is required, but it was not provided.',
+ 'Argument .__type(name:) of type "String!" is required, but it was not provided.',
locations: [{ line: 3, column: 9 }],
},
],
diff --git a/src/type/__tests__/predicate-test.ts b/src/type/__tests__/predicate-test.ts
index c1e1fb3059d..5bd680d7675 100644
--- a/src/type/__tests__/predicate-test.ts
+++ b/src/type/__tests__/predicate-test.ts
@@ -3,11 +3,7 @@ import { describe, it } from 'mocha';
import { DirectiveLocation } from '../../language/directiveLocation.js';
-import type {
- GraphQLArgument,
- GraphQLInputField,
- GraphQLInputType,
-} from '../definition.js';
+import type { GraphQLInputType } from '../definition.js';
import {
assertAbstractType,
assertCompositeType,
@@ -28,7 +24,9 @@ import {
assertWrappingType,
getNamedType,
getNullableType,
+ GraphQLArgument,
GraphQLEnumType,
+ GraphQLInputField,
GraphQLInputObjectType,
GraphQLInterfaceType,
GraphQLList,
@@ -570,15 +568,7 @@ describe('Type predicates', () => {
type: GraphQLInputType;
defaultValue?: unknown;
}): GraphQLArgument {
- return {
- name: 'someArg',
- type: config.type,
- description: undefined,
- defaultValue: config.defaultValue,
- deprecationReason: null,
- extensions: Object.create(null),
- astNode: undefined,
- };
+ return new GraphQLArgument('SomeType.someField', 'someArg', config);
}
it('returns true for required arguments', () => {
@@ -618,15 +608,7 @@ describe('Type predicates', () => {
type: GraphQLInputType;
defaultValue?: unknown;
}): GraphQLInputField {
- return {
- name: 'someInputField',
- type: config.type,
- description: undefined,
- defaultValue: config.defaultValue,
- deprecationReason: null,
- extensions: Object.create(null),
- astNode: undefined,
- };
+ return new GraphQLInputField('SomeType', 'someInputField', config);
}
it('returns true for required input field', () => {
diff --git a/src/type/__tests__/validation-test.ts b/src/type/__tests__/validation-test.ts
index 7d215361f94..cb724a08e68 100644
--- a/src/type/__tests__/validation-test.ts
+++ b/src/type/__tests__/validation-test.ts
@@ -2072,7 +2072,7 @@ describe('Objects must adhere to Interface they implement', () => {
expectJSON(validateSchema(schema)).toDeepEqual([
{
message:
- 'Object field AnotherObject.field includes required argument requiredArg that is missing from the Interface field AnotherInterface.field.',
+ 'Argument AnotherObject.field(requiredArg:) must not be required type String! if not provided by the Interface field AnotherInterface.field.',
locations: [
{ line: 13, column: 11 },
{ line: 7, column: 9 },
@@ -2267,11 +2267,11 @@ describe('Interfaces must adhere to Interface they implement', () => {
}
interface ParentInterface {
- field(input: String): String
+ field(input: String!): String
}
interface ChildInterface implements ParentInterface {
- field(input: String, anotherInput: String): String
+ field(input: String!, anotherInput: String): String
}
`);
expectJSON(validateSchema(schema)).toDeepEqual([]);
@@ -2529,7 +2529,7 @@ describe('Interfaces must adhere to Interface they implement', () => {
expectJSON(validateSchema(schema)).toDeepEqual([
{
message:
- 'Object field ChildInterface.field includes required argument requiredArg that is missing from the Interface field ParentInterface.field.',
+ 'Argument ChildInterface.field(requiredArg:) must not be required type String! if not provided by the Interface field ParentInterface.field.',
locations: [
{ line: 13, column: 11 },
{ line: 7, column: 9 },
diff --git a/src/type/definition.ts b/src/type/definition.ts
index 0ca4152bd2f..913df14e7cf 100644
--- a/src/type/definition.ts
+++ b/src/type/definition.ts
@@ -481,6 +481,31 @@ export function getNamedType(
}
}
+/**
+ * The base class for all Schema Elements.
+ */
+export class GraphQLSchemaElement {
+ readonly coordinate: string;
+
+ constructor(coordinate: string) {
+ this.coordinate = coordinate;
+ }
+
+ // TODO: add coverage
+ /* c8 ignore next 3*/
+ get [Symbol.toStringTag]() {
+ return 'GraphQLSchemaElement';
+ }
+
+ toString(): string {
+ return this.coordinate;
+ }
+
+ toJSON(): string {
+ return this.toString();
+ }
+}
+
/**
* Used while defining GraphQL types to allow for circular references in
* otherwise immutable type definitions.
@@ -542,7 +567,10 @@ export interface GraphQLScalarTypeExtensions {
* });
* ```
*/
-export class GraphQLScalarType {
+export class GraphQLScalarType<
+ TInternal = unknown,
+ TExternal = TInternal,
+> extends GraphQLSchemaElement {
name: string;
description: Maybe;
specifiedByURL: Maybe;
@@ -554,6 +582,7 @@ export class GraphQLScalarType {
extensionASTNodes: ReadonlyArray;
constructor(config: Readonly>) {
+ super(config.name);
const parseValue =
config.parseValue ??
(identityFunc as GraphQLScalarValueParser);
@@ -597,14 +626,6 @@ export class GraphQLScalarType {
extensionASTNodes: this.extensionASTNodes,
};
}
-
- toString(): string {
- return this.name;
- }
-
- toJSON(): string {
- return this.toString();
- }
}
export type GraphQLScalarSerializer = (
@@ -700,7 +721,10 @@ export interface GraphQLObjectTypeExtensions<_TSource = any, _TContext = any> {
* });
* ```
*/
-export class GraphQLObjectType {
+export class GraphQLObjectType<
+ TSource = any,
+ TContext = any,
+> extends GraphQLSchemaElement {
name: string;
description: Maybe;
isTypeOf: Maybe>;
@@ -712,6 +736,7 @@ export class GraphQLObjectType {
private _interfaces: ThunkReadonlyArray;
constructor(config: Readonly>) {
+ super(config.name);
this.name = assertName(config.name);
this.description = config.description;
this.isTypeOf = config.isTypeOf;
@@ -721,7 +746,7 @@ export class GraphQLObjectType {
// prettier-ignore
// FIXME: blocked by https://github.com/prettier/prettier/issues/14625
- this._fields = (defineFieldMap).bind(undefined, config.fields);
+ this._fields = (defineFieldMap).bind(undefined, this.name, config.fields);
this._interfaces = defineInterfaces.bind(undefined, config.interfaces);
}
@@ -748,21 +773,13 @@ export class GraphQLObjectType {
name: this.name,
description: this.description,
interfaces: this.getInterfaces(),
- fields: fieldsToFieldsConfig(this.getFields()),
+ fields: mapValue(this.getFields(), (field) => field.toConfig()),
isTypeOf: this.isTypeOf,
extensions: this.extensions,
astNode: this.astNode,
extensionASTNodes: this.extensionASTNodes,
};
}
-
- toString(): string {
- return this.name;
- }
-
- toJSON(): string {
- return this.toString();
- }
}
function defineInterfaces(
@@ -772,72 +789,15 @@ function defineInterfaces(
}
function defineFieldMap(
+ parentCoordinate: string,
fields: ThunkObjMap>,
): GraphQLFieldMap {
const fieldMap = resolveObjMapThunk(fields);
- return mapValue(fieldMap, (fieldConfig, fieldName) => {
- const argsConfig = fieldConfig.args ?? {};
- return {
- name: assertName(fieldName),
- description: fieldConfig.description,
- type: fieldConfig.type,
- args: defineArguments(argsConfig),
- resolve: fieldConfig.resolve,
- subscribe: fieldConfig.subscribe,
- deprecationReason: fieldConfig.deprecationReason,
- extensions: toObjMap(fieldConfig.extensions),
- astNode: fieldConfig.astNode,
- };
- });
-}
-
-export function defineArguments(
- args: GraphQLFieldConfigArgumentMap,
-): ReadonlyArray {
- return Object.entries(args).map(([argName, argConfig]) => ({
- name: assertName(argName),
- description: argConfig.description,
- type: argConfig.type,
- defaultValue: argConfig.defaultValue,
- deprecationReason: argConfig.deprecationReason,
- extensions: toObjMap(argConfig.extensions),
- astNode: argConfig.astNode,
- }));
-}
-
-function fieldsToFieldsConfig(
- fields: GraphQLFieldMap,
-): GraphQLFieldConfigMap {
- return mapValue(fields, (field) => ({
- description: field.description,
- type: field.type,
- args: argsToArgsConfig(field.args),
- resolve: field.resolve,
- subscribe: field.subscribe,
- deprecationReason: field.deprecationReason,
- extensions: field.extensions,
- astNode: field.astNode,
- }));
-}
-
-/**
- * @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,
- }),
+ return mapValue(
+ fieldMap,
+ (fieldConfig, fieldName) =>
+ new GraphQLField(parentCoordinate, fieldName, fieldConfig),
);
}
@@ -955,7 +915,11 @@ export type GraphQLFieldConfigMap = ObjMap<
GraphQLFieldConfig
>;
-export interface GraphQLField {
+export class GraphQLField<
+ TSource,
+ TContext,
+ TArgs = { [argument: string]: any },
+> extends GraphQLSchemaElement {
name: string;
description: Maybe;
type: GraphQLOutputType;
@@ -965,9 +929,56 @@ export interface GraphQLField {
deprecationReason: Maybe;
extensions: Readonly>;
astNode: Maybe;
+
+ constructor(
+ parentCoordinate: string,
+ name: string,
+ config: GraphQLFieldConfig,
+ ) {
+ const coordinate = `${parentCoordinate}.${name}`;
+ super(coordinate);
+ this.name = assertName(name);
+ this.description = config.description;
+ this.type = config.type;
+
+ const argsConfig = config.args;
+ this.args = argsConfig
+ ? Object.entries(argsConfig).map(
+ ([argName, argConfig]) =>
+ new GraphQLArgument(coordinate, argName, argConfig),
+ )
+ : [];
+
+ this.resolve = config.resolve;
+ this.subscribe = config.subscribe;
+ this.deprecationReason = config.deprecationReason;
+ this.extensions = toObjMap(config.extensions);
+ this.astNode = config.astNode;
+ }
+
+ get [Symbol.toStringTag]() {
+ return 'GraphQLField';
+ }
+
+ toConfig(): GraphQLFieldConfig {
+ return {
+ description: this.description,
+ type: this.type,
+ args: keyValMap(
+ this.args,
+ (arg) => arg.name,
+ (arg) => arg.toConfig(),
+ ),
+ resolve: this.resolve,
+ subscribe: this.subscribe,
+ deprecationReason: this.deprecationReason,
+ extensions: this.extensions,
+ astNode: this.astNode,
+ };
+ }
}
-export interface GraphQLArgument {
+export class GraphQLArgument extends GraphQLSchemaElement {
name: string;
description: Maybe;
type: GraphQLInputType;
@@ -975,6 +986,37 @@ export interface GraphQLArgument {
deprecationReason: Maybe;
extensions: Readonly;
astNode: Maybe;
+
+ constructor(
+ parentCoordinate: string,
+ name: string,
+ config: GraphQLArgumentConfig,
+ ) {
+ const coordinate = `${parentCoordinate}(${name}:)`;
+ super(coordinate);
+ this.name = assertName(name);
+ this.description = config.description;
+ this.type = config.type;
+ this.defaultValue = config.defaultValue;
+ this.deprecationReason = config.deprecationReason;
+ this.extensions = toObjMap(config.extensions);
+ this.astNode = config.astNode;
+ }
+
+ get [Symbol.toStringTag]() {
+ return 'GraphQLArgument';
+ }
+
+ toConfig(): GraphQLArgumentConfig {
+ return {
+ description: this.description,
+ type: this.type,
+ defaultValue: this.defaultValue,
+ deprecationReason: this.deprecationReason,
+ extensions: this.extensions,
+ astNode: this.astNode,
+ };
+ }
}
export function isRequiredArgument(arg: GraphQLArgument): boolean {
@@ -1017,7 +1059,10 @@ export interface GraphQLInterfaceTypeExtensions {
* });
* ```
*/
-export class GraphQLInterfaceType {
+export class GraphQLInterfaceType<
+ TSource = any,
+ TContext = any,
+> extends GraphQLSchemaElement {
name: string;
description: Maybe;
resolveType: Maybe>;
@@ -1029,6 +1074,7 @@ export class GraphQLInterfaceType {
private _interfaces: ThunkReadonlyArray;
constructor(config: Readonly>) {
+ super(config.name);
this.name = assertName(config.name);
this.description = config.description;
this.resolveType = config.resolveType;
@@ -1038,7 +1084,7 @@ export class GraphQLInterfaceType {
// prettier-ignore
// FIXME: blocked by https://github.com/prettier/prettier/issues/14625
- this._fields = (defineFieldMap).bind(undefined, config.fields);
+ this._fields = (defineFieldMap).bind(undefined, this.name, config.fields);
this._interfaces = defineInterfaces.bind(undefined, config.interfaces);
}
@@ -1065,21 +1111,13 @@ export class GraphQLInterfaceType {
name: this.name,
description: this.description,
interfaces: this.getInterfaces(),
- fields: fieldsToFieldsConfig(this.getFields()),
+ fields: mapValue(this.getFields(), (field) => field.toConfig()),
resolveType: this.resolveType,
extensions: this.extensions,
astNode: this.astNode,
extensionASTNodes: this.extensionASTNodes,
};
}
-
- toString(): string {
- return this.name;
- }
-
- toJSON(): string {
- return this.toString();
- }
}
export interface GraphQLInterfaceTypeConfig {
@@ -1143,7 +1181,7 @@ export interface GraphQLUnionTypeExtensions {
* });
* ```
*/
-export class GraphQLUnionType {
+export class GraphQLUnionType extends GraphQLSchemaElement {
name: string;
description: Maybe;
resolveType: Maybe>;
@@ -1154,6 +1192,7 @@ export class GraphQLUnionType {
private _types: ThunkReadonlyArray;
constructor(config: Readonly>) {
+ super(config.name);
this.name = assertName(config.name);
this.description = config.description;
this.resolveType = config.resolveType;
@@ -1186,14 +1225,6 @@ export class GraphQLUnionType {
extensionASTNodes: this.extensionASTNodes,
};
}
-
- toString(): string {
- return this.name;
- }
-
- toJSON(): string {
- return this.toString();
- }
}
function defineTypes(
@@ -1260,7 +1291,7 @@ export interface GraphQLEnumTypeExtensions {
* Note: If a value is not provided in a definition, the name of the enum value
* will be used as its internal value.
*/
-export class GraphQLEnumType /* */ {
+export class GraphQLEnumType /* */ extends GraphQLSchemaElement {
name: string;
description: Maybe;
extensions: Readonly;
@@ -1272,6 +1303,7 @@ export class GraphQLEnumType /* */ {
private _nameLookup: ObjMap;
constructor(config: Readonly */>) {
+ super(config.name);
this.name = assertName(config.name);
this.description = config.description;
this.extensions = toObjMap(config.extensions);
@@ -1279,14 +1311,8 @@ export class GraphQLEnumType /* */ {
this.extensionASTNodes = config.extensionASTNodes ?? [];
this._values = Object.entries(config.values).map(
- ([valueName, valueConfig]) => ({
- name: assertEnumValueName(valueName),
- description: valueConfig.description,
- value: valueConfig.value !== undefined ? valueConfig.value : valueName,
- deprecationReason: valueConfig.deprecationReason,
- extensions: toObjMap(valueConfig.extensions),
- astNode: valueConfig.astNode,
- }),
+ ([valueName, valueConfig]) =>
+ new GraphQLEnumValue(config.name, valueName, valueConfig),
);
this._valueLookup = new Map(
this._values.map((enumValue) => [enumValue.value, enumValue]),
@@ -1362,35 +1388,19 @@ export class GraphQLEnumType /* */ {
}
toConfig(): GraphQLEnumTypeNormalizedConfig {
- const values = keyValMap(
- this.getValues(),
- (value) => value.name,
- (value) => ({
- description: value.description,
- value: value.value,
- deprecationReason: value.deprecationReason,
- extensions: value.extensions,
- astNode: value.astNode,
- }),
- );
-
return {
name: this.name,
description: this.description,
- values,
+ values: keyValMap(
+ this.getValues(),
+ (value) => value.name,
+ (value) => value.toConfig(),
+ ),
extensions: this.extensions,
astNode: this.astNode,
extensionASTNodes: this.extensionASTNodes,
};
}
-
- toString(): string {
- return this.name;
- }
-
- toJSON(): string {
- return this.toString();
- }
}
function didYouMeanEnumValue(
@@ -1441,13 +1451,43 @@ export interface GraphQLEnumValueConfig {
astNode?: Maybe;
}
-export interface GraphQLEnumValue {
+export class GraphQLEnumValue extends GraphQLSchemaElement {
name: string;
description: Maybe;
value: any /* T */;
deprecationReason: Maybe;
extensions: Readonly;
astNode: Maybe;
+
+ constructor(
+ parentCoordinate: string,
+ name: string,
+ config: GraphQLEnumValueConfig,
+ ) {
+ const coordinate = `${parentCoordinate}.${name}`;
+ super(coordinate);
+
+ this.name = assertEnumValueName(name);
+ this.description = config.description;
+ this.value = config.value !== undefined ? config.value : name;
+ this.deprecationReason = config.deprecationReason;
+ this.extensions = toObjMap(config.extensions);
+ this.astNode = config.astNode;
+ }
+
+ get [Symbol.toStringTag]() {
+ return 'GraphQLEnumValue';
+ }
+
+ toConfig(): GraphQLEnumValueConfig {
+ return {
+ description: this.description,
+ value: this.value,
+ deprecationReason: this.deprecationReason,
+ extensions: this.extensions,
+ astNode: this.astNode,
+ };
+ }
}
/**
@@ -1484,7 +1524,7 @@ export interface GraphQLInputObjectTypeExtensions {
* });
* ```
*/
-export class GraphQLInputObjectType {
+export class GraphQLInputObjectType extends GraphQLSchemaElement {
name: string;
description: Maybe;
extensions: Readonly;
@@ -1495,6 +1535,7 @@ export class GraphQLInputObjectType {
private _fields: ThunkObjMap;
constructor(config: Readonly) {
+ super(config.name);
this.name = assertName(config.name);
this.description = config.description;
this.extensions = toObjMap(config.extensions);
@@ -1502,7 +1543,11 @@ export class GraphQLInputObjectType {
this.extensionASTNodes = config.extensionASTNodes ?? [];
this.isOneOf = config.isOneOf ?? false;
- this._fields = defineInputFieldMap.bind(undefined, config.fields);
+ this._fields = defineInputFieldMap.bind(
+ undefined,
+ this.name,
+ config.fields,
+ );
}
get [Symbol.toStringTag]() {
@@ -1517,48 +1562,28 @@ export class GraphQLInputObjectType {
}
toConfig(): GraphQLInputObjectTypeNormalizedConfig {
- const fields = mapValue(this.getFields(), (field) => ({
- description: field.description,
- type: field.type,
- defaultValue: field.defaultValue,
- deprecationReason: field.deprecationReason,
- extensions: field.extensions,
- astNode: field.astNode,
- }));
-
return {
name: this.name,
description: this.description,
- fields,
+ fields: mapValue(this.getFields(), (field) => field.toConfig()),
extensions: this.extensions,
astNode: this.astNode,
extensionASTNodes: this.extensionASTNodes,
isOneOf: this.isOneOf,
};
}
-
- toString(): string {
- return this.name;
- }
-
- toJSON(): string {
- return this.toString();
- }
}
function defineInputFieldMap(
+ parentCoordinate: string,
fields: ThunkObjMap,
): GraphQLInputFieldMap {
const fieldMap = resolveObjMapThunk(fields);
- return mapValue(fieldMap, (fieldConfig, fieldName) => ({
- name: assertName(fieldName),
- description: fieldConfig.description,
- type: fieldConfig.type,
- defaultValue: fieldConfig.defaultValue,
- deprecationReason: fieldConfig.deprecationReason,
- extensions: toObjMap(fieldConfig.extensions),
- astNode: fieldConfig.astNode,
- }));
+ return mapValue(
+ fieldMap,
+ (fieldConfig, fieldName) =>
+ new GraphQLInputField(parentCoordinate, fieldName, fieldConfig),
+ );
}
export interface GraphQLInputObjectTypeConfig {
@@ -1602,7 +1627,7 @@ export interface GraphQLInputFieldConfig {
export type GraphQLInputFieldConfigMap = ObjMap;
-export interface GraphQLInputField {
+export class GraphQLInputField extends GraphQLSchemaElement {
name: string;
description: Maybe;
type: GraphQLInputType;
@@ -1610,6 +1635,43 @@ export interface GraphQLInputField {
deprecationReason: Maybe;
extensions: Readonly;
astNode: Maybe;
+
+ constructor(
+ parentCoordinate: string,
+ name: string,
+ config: GraphQLInputFieldConfig,
+ ) {
+ const coordinate = `${parentCoordinate}.${name}`;
+
+ devAssert(
+ !('resolve' in config),
+ `${coordinate} field has a resolve property, but Input Types cannot define resolvers.`,
+ );
+
+ super(coordinate);
+ this.name = assertName(name);
+ this.description = config.description;
+ this.type = config.type;
+ this.defaultValue = config.defaultValue;
+ this.deprecationReason = config.deprecationReason;
+ this.extensions = toObjMap(config.extensions);
+ this.astNode = config.astNode;
+ }
+
+ get [Symbol.toStringTag]() {
+ return 'GraphQLInputField';
+ }
+
+ toConfig(): GraphQLInputFieldConfig {
+ return {
+ description: this.description,
+ type: this.type,
+ defaultValue: this.defaultValue,
+ deprecationReason: this.deprecationReason,
+ extensions: this.extensions,
+ astNode: this.astNode,
+ };
+ }
}
export function isRequiredInputField(field: GraphQLInputField): boolean {
diff --git a/src/type/directives.ts b/src/type/directives.ts
index 48e90c55319..e54c74013ba 100644
--- a/src/type/directives.ts
+++ b/src/type/directives.ts
@@ -1,20 +1,21 @@
+import { devAssert } from '../jsutils/devAssert.js';
import { inspect } from '../jsutils/inspect.js';
import { instanceOf } from '../jsutils/instanceOf.js';
+import { isObjectLike } from '../jsutils/isObjectLike.js';
+import { keyValMap } from '../jsutils/keyValMap.js';
import type { Maybe } from '../jsutils/Maybe.js';
+import type { ObjMap } from '../jsutils/ObjMap.js';
import { toObjMap } from '../jsutils/toObjMap.js';
import type { DirectiveDefinitionNode } from '../language/ast.js';
import { DirectiveLocation } from '../language/directiveLocation.js';
import { assertName } from './assertName.js';
-import type {
- GraphQLArgument,
- GraphQLFieldConfigArgumentMap,
-} from './definition.js';
+import type { GraphQLArgumentConfig } from './definition.js';
import {
- argsToArgsConfig,
- defineArguments,
+ GraphQLArgument,
GraphQLNonNull,
+ GraphQLSchemaElement,
} from './definition.js';
import { GraphQLBoolean, GraphQLInt, GraphQLString } from './scalars.js';
@@ -51,7 +52,7 @@ export interface GraphQLDirectiveExtensions {
* Directives are used by the GraphQL runtime as a way of modifying execution
* behavior. Type system creators will usually not create these directly.
*/
-export class GraphQLDirective {
+export class GraphQLDirective extends GraphQLSchemaElement {
name: string;
description: Maybe;
locations: ReadonlyArray;
@@ -61,6 +62,8 @@ export class GraphQLDirective {
astNode: Maybe;
constructor(config: Readonly) {
+ const coordinate = `@${config.name}`;
+ super(coordinate);
this.name = assertName(config.name);
this.description = config.description;
this.locations = config.locations;
@@ -68,8 +71,21 @@ export class GraphQLDirective {
this.extensions = toObjMap(config.extensions);
this.astNode = config.astNode;
+ devAssert(
+ Array.isArray(config.locations),
+ `${coordinate} locations must be an Array.`,
+ );
+
const args = config.args ?? {};
- this.args = defineArguments(args);
+ devAssert(
+ isObjectLike(args) && !Array.isArray(args),
+ `${coordinate} args must be an object with argument names as keys.`,
+ );
+
+ this.args = Object.entries(args).map(
+ ([argName, argConfig]) =>
+ new GraphQLArgument(coordinate, argName, argConfig),
+ );
}
get [Symbol.toStringTag]() {
@@ -81,34 +97,30 @@ export class GraphQLDirective {
name: this.name,
description: this.description,
locations: this.locations,
- args: argsToArgsConfig(this.args),
+ args: keyValMap(
+ this.args,
+ (arg) => arg.name,
+ (arg) => arg.toConfig(),
+ ),
isRepeatable: this.isRepeatable,
extensions: this.extensions,
astNode: this.astNode,
};
}
-
- toString(): string {
- return '@' + this.name;
- }
-
- toJSON(): string {
- return this.toString();
- }
}
export interface GraphQLDirectiveConfig {
name: string;
description?: Maybe;
locations: ReadonlyArray;
- args?: Maybe;
+ args?: Maybe>;
isRepeatable?: Maybe;
extensions?: Maybe>;
astNode?: Maybe;
}
interface GraphQLDirectiveNormalizedConfig extends GraphQLDirectiveConfig {
- args: GraphQLFieldConfigArgumentMap;
+ args: ObjMap;
isRepeatable: boolean;
extensions: Readonly;
}
diff --git a/src/type/index.ts b/src/type/index.ts
index 6617a7bfe17..d2255995f2a 100644
--- a/src/type/index.ts
+++ b/src/type/index.ts
@@ -55,12 +55,17 @@ export {
getNullableType,
getNamedType,
// Definitions
+ GraphQLSchemaElement,
GraphQLScalarType,
GraphQLObjectType,
GraphQLInterfaceType,
GraphQLUnionType,
GraphQLEnumType,
GraphQLInputObjectType,
+ GraphQLField,
+ GraphQLArgument,
+ GraphQLEnumValue,
+ GraphQLInputField,
// Type Wrappers
GraphQLList,
GraphQLNonNull,
@@ -82,23 +87,19 @@ export type {
GraphQLNamedOutputType,
ThunkReadonlyArray,
ThunkObjMap,
- GraphQLArgument,
GraphQLArgumentConfig,
GraphQLArgumentExtensions,
GraphQLEnumTypeConfig,
GraphQLEnumTypeExtensions,
- GraphQLEnumValue,
GraphQLEnumValueConfig,
GraphQLEnumValueConfigMap,
GraphQLEnumValueExtensions,
- GraphQLField,
GraphQLFieldConfig,
GraphQLFieldConfigArgumentMap,
GraphQLFieldConfigMap,
GraphQLFieldExtensions,
GraphQLFieldMap,
GraphQLFieldResolver,
- GraphQLInputField,
GraphQLInputFieldConfig,
GraphQLInputFieldConfigMap,
GraphQLInputFieldExtensions,
diff --git a/src/type/introspection.ts b/src/type/introspection.ts
index 5f3c9c1fa5b..8419025ed9a 100644
--- a/src/type/introspection.ts
+++ b/src/type/introspection.ts
@@ -8,7 +8,6 @@ import { astFromValue } from '../utilities/astFromValue.js';
import type {
GraphQLEnumValue,
- GraphQLField,
GraphQLFieldConfigMap,
GraphQLInputField,
GraphQLNamedType,
@@ -16,6 +15,7 @@ import type {
} from './definition.js';
import {
GraphQLEnumType,
+ GraphQLField,
GraphQLList,
GraphQLNonNull,
GraphQLObjectType,
@@ -499,53 +499,24 @@ export const __TypeKind: GraphQLEnumType = new GraphQLEnumType({
},
});
-/**
- * Note that these are GraphQLField and not GraphQLFieldConfig,
- * so the format for args is different.
- */
-
-export const SchemaMetaFieldDef: GraphQLField = {
- name: '__schema',
+export const SchemaMetaFieldDef = new GraphQLField('', '__schema', {
type: new GraphQLNonNull(__Schema),
description: 'Access the current type schema of this server.',
- args: [],
resolve: (_source, _args, _context, { schema }) => schema,
- deprecationReason: undefined,
- extensions: Object.create(null),
- astNode: undefined,
-};
+});
-export const TypeMetaFieldDef: GraphQLField = {
- name: '__type',
+export const TypeMetaFieldDef = new GraphQLField('', '__type', {
type: __Type,
description: 'Request the type information of a single type.',
- args: [
- {
- name: 'name',
- description: undefined,
- type: new GraphQLNonNull(GraphQLString),
- defaultValue: undefined,
- deprecationReason: undefined,
- extensions: Object.create(null),
- astNode: undefined,
- },
- ],
+ args: { name: { type: new GraphQLNonNull(GraphQLString) } },
resolve: (_source, { name }, _context, { schema }) => schema.getType(name),
- deprecationReason: undefined,
- extensions: Object.create(null),
- astNode: undefined,
-};
+});
-export const TypeNameMetaFieldDef: GraphQLField = {
- name: '__typename',
+export const TypeNameMetaFieldDef = new GraphQLField('', '__typename', {
type: new GraphQLNonNull(GraphQLString),
description: 'The name of the current Object type at runtime.',
- args: [],
resolve: (_source, _args, _context, { parentType }) => parentType.name,
- deprecationReason: undefined,
- extensions: Object.create(null),
- astNode: undefined,
-};
+});
export const introspectionTypes: ReadonlyArray =
Object.freeze([
diff --git a/src/type/validate.ts b/src/type/validate.ts
index deee23a3722..1f7c3ce6d90 100644
--- a/src/type/validate.ts
+++ b/src/type/validate.ts
@@ -193,17 +193,17 @@ function validateDirectives(context: SchemaValidationContext): void {
// Ensure the type is an input type.
if (!isInputType(arg.type)) {
context.reportError(
- `The type of @${directive.name}(${arg.name}:) must be Input Type ` +
+ `The type of ${arg} must be Input Type ` +
`but got: ${inspect(arg.type)}.`,
arg.astNode,
);
}
if (isRequiredArgument(arg) && arg.deprecationReason != null) {
- context.reportError(
- `Required argument @${directive.name}(${arg.name}:) cannot be deprecated.`,
- [getDeprecatedDirectiveNode(arg.astNode), arg.astNode?.type],
- );
+ context.reportError(`Required argument ${arg} cannot be deprecated.`, [
+ getDeprecatedDirectiveNode(arg.astNode),
+ arg.astNode?.type,
+ ]);
}
}
}
@@ -277,7 +277,7 @@ function validateFields(
// Objects and Interfaces both must define one or more fields.
if (fields.length === 0) {
- context.reportError(`Type ${type.name} must define one or more fields.`, [
+ context.reportError(`Type ${type} must define one or more fields.`, [
type.astNode,
...type.extensionASTNodes,
]);
@@ -290,7 +290,7 @@ function validateFields(
// Ensure the type is an output type
if (!isOutputType(field.type)) {
context.reportError(
- `The type of ${type.name}.${field.name} must be Output Type ` +
+ `The type of ${field} must be Output Type ` +
`but got: ${inspect(field.type)}.`,
field.astNode?.type,
);
@@ -298,25 +298,23 @@ function validateFields(
// Ensure the arguments are valid
for (const arg of field.args) {
- const argName = arg.name;
-
// Ensure they are named correctly.
validateName(context, arg);
// Ensure the type is an input type
if (!isInputType(arg.type)) {
context.reportError(
- `The type of ${type.name}.${field.name}(${argName}:) must be Input ` +
+ `The type of ${arg} must be Input ` +
`Type but got: ${inspect(arg.type)}.`,
arg.astNode?.type,
);
}
if (isRequiredArgument(arg) && arg.deprecationReason != null) {
- context.reportError(
- `Required argument ${type.name}.${field.name}(${argName}:) cannot be deprecated.`,
- [getDeprecatedDirectiveNode(arg.astNode), arg.astNode?.type],
- );
+ context.reportError(`Required argument ${arg} cannot be deprecated.`, [
+ getDeprecatedDirectiveNode(arg.astNode),
+ arg.astNode?.type,
+ ]);
}
}
}
@@ -330,7 +328,7 @@ function validateInterfaces(
for (const iface of type.getInterfaces()) {
if (!isInterfaceType(iface)) {
context.reportError(
- `Type ${inspect(type)} must only implement Interface types, ` +
+ `Type ${type} must only implement Interface types, ` +
`it cannot implement ${inspect(iface)}.`,
getAllImplementsInterfaceNodes(type, iface),
);
@@ -339,7 +337,7 @@ function validateInterfaces(
if (type === iface) {
context.reportError(
- `Type ${type.name} cannot implement itself because it would create a circular reference.`,
+ `Type ${type} cannot implement itself because it would create a circular reference.`,
getAllImplementsInterfaceNodes(type, iface),
);
continue;
@@ -347,7 +345,7 @@ function validateInterfaces(
if (ifaceTypeNames.has(iface.name)) {
context.reportError(
- `Type ${type.name} can only implement ${iface.name} once.`,
+ `Type ${type} can only implement ${iface} once.`,
getAllImplementsInterfaceNodes(type, iface),
);
continue;
@@ -369,13 +367,12 @@ function validateTypeImplementsInterface(
// Assert each interface field is implemented.
for (const ifaceField of Object.values(iface.getFields())) {
- const fieldName = ifaceField.name;
- const typeField = typeFieldMap[fieldName];
+ const typeField = typeFieldMap[ifaceField.name];
// Assert interface field exists on type.
if (typeField == null) {
context.reportError(
- `Interface field ${iface.name}.${fieldName} expected but ${type.name} does not provide it.`,
+ `Interface field ${ifaceField} expected but ${type} does not provide it.`,
[ifaceField.astNode, type.astNode, ...type.extensionASTNodes],
);
continue;
@@ -385,22 +382,20 @@ function validateTypeImplementsInterface(
// a valid subtype. (covariant)
if (!isTypeSubTypeOf(context.schema, typeField.type, ifaceField.type)) {
context.reportError(
- `Interface field ${iface.name}.${fieldName} expects type ` +
- `${inspect(ifaceField.type)} but ${type.name}.${fieldName} ` +
- `is type ${inspect(typeField.type)}.`,
+ `Interface field ${ifaceField} expects type ${ifaceField.type} ` +
+ `but ${typeField} is type ${typeField.type}.`,
[ifaceField.astNode?.type, typeField.astNode?.type],
);
}
// Assert each interface field arg is implemented.
for (const ifaceArg of ifaceField.args) {
- const argName = ifaceArg.name;
- const typeArg = typeField.args.find((arg) => arg.name === argName);
+ const typeArg = typeField.args.find((arg) => arg.name === ifaceArg.name);
// Assert interface field arg exists on object field.
if (!typeArg) {
context.reportError(
- `Interface field argument ${iface.name}.${fieldName}(${argName}:) expected but ${type.name}.${fieldName} does not provide it.`,
+ `Interface field argument ${ifaceArg} expected but ${typeField} does not provide it.`,
[ifaceArg.astNode, typeField.astNode],
);
continue;
@@ -411,10 +406,8 @@ function validateTypeImplementsInterface(
// TODO: change to contravariant?
if (!isEqualType(ifaceArg.type, typeArg.type)) {
context.reportError(
- `Interface field argument ${iface.name}.${fieldName}(${argName}:) ` +
- `expects type ${inspect(ifaceArg.type)} but ` +
- `${type.name}.${fieldName}(${argName}:) is type ` +
- `${inspect(typeArg.type)}.`,
+ `Interface field argument ${ifaceArg} expects type ${ifaceArg.type} ` +
+ `but ${typeArg} is type ${typeArg.type}.`,
[ifaceArg.astNode?.type, typeArg.astNode?.type],
);
}
@@ -424,13 +417,17 @@ function validateTypeImplementsInterface(
// Assert additional arguments must not be required.
for (const typeArg of typeField.args) {
- const argName = typeArg.name;
- const ifaceArg = ifaceField.args.find((arg) => arg.name === argName);
- if (!ifaceArg && isRequiredArgument(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],
+ if (isRequiredArgument(typeArg)) {
+ const ifaceArg = ifaceField.args.find(
+ (arg) => arg.name === typeArg.name,
);
+ if (!ifaceArg) {
+ context.reportError(
+ `Argument ${typeArg} must not be required type ${typeArg.type} ` +
+ `if not provided by the Interface field ${ifaceField}.`,
+ [typeArg.astNode, ifaceField.astNode],
+ );
+ }
}
}
}
@@ -446,8 +443,8 @@ function validateTypeImplementsAncestors(
if (!ifaceInterfaces.includes(transitive)) {
context.reportError(
transitive === type
- ? `Type ${type.name} cannot implement ${iface.name} because it would create a circular reference.`
- : `Type ${type.name} must implement ${transitive.name} because it is implemented by ${iface.name}.`,
+ ? `Type ${type} cannot implement ${iface} because it would create a circular reference.`
+ : `Type ${type} must implement ${transitive} because it is implemented by ${iface}.`,
[
...getAllImplementsInterfaceNodes(iface, transitive),
...getAllImplementsInterfaceNodes(type, iface),
@@ -465,7 +462,7 @@ function validateUnionMembers(
if (memberTypes.length === 0) {
context.reportError(
- `Union type ${union.name} must define one or more member types.`,
+ `Union type ${union} must define one or more member types.`,
[union.astNode, ...union.extensionASTNodes],
);
}
@@ -474,7 +471,7 @@ function validateUnionMembers(
for (const memberType of memberTypes) {
if (includedTypeNames.has(memberType.name)) {
context.reportError(
- `Union type ${union.name} can only include type ${memberType.name} once.`,
+ `Union type ${union} can only include type ${memberType} once.`,
getUnionMemberTypeNodes(union, memberType.name),
);
continue;
@@ -482,7 +479,7 @@ function validateUnionMembers(
includedTypeNames.add(memberType.name);
if (!isObjectType(memberType)) {
context.reportError(
- `Union type ${union.name} can only include Object types, ` +
+ `Union type ${union} can only include Object types, ` +
`it cannot include ${inspect(memberType)}.`,
getUnionMemberTypeNodes(union, String(memberType)),
);
@@ -498,7 +495,7 @@ function validateEnumValues(
if (enumValues.length === 0) {
context.reportError(
- `Enum type ${enumType.name} must define one or more values.`,
+ `Enum type ${enumType} must define one or more values.`,
[enumType.astNode, ...enumType.extensionASTNodes],
);
}
@@ -517,7 +514,7 @@ function validateInputFields(
if (fields.length === 0) {
context.reportError(
- `Input Object type ${inputObj.name} must define one or more fields.`,
+ `Input Object type ${inputObj} must define one or more fields.`,
[inputObj.astNode, ...inputObj.extensionASTNodes],
);
}
@@ -530,7 +527,7 @@ function validateInputFields(
// Ensure the type is an input type
if (!isInputType(field.type)) {
context.reportError(
- `The type of ${inputObj.name}.${field.name} must be Input Type ` +
+ `The type of ${field} must be Input Type ` +
`but got: ${inspect(field.type)}.`,
field.astNode?.type,
);
@@ -538,7 +535,7 @@ function validateInputFields(
if (isRequiredInputField(field) && field.deprecationReason != null) {
context.reportError(
- `Required input field ${inputObj.name}.${field.name} cannot be deprecated.`,
+ `Required input field ${field} cannot be deprecated.`,
[getDeprecatedDirectiveNode(field.astNode), field.astNode?.type],
);
}
@@ -609,7 +606,7 @@ function createInputObjectCircularRefsValidator(
const cyclePath = fieldPath.slice(cycleIndex);
const pathStr = cyclePath.map((fieldObj) => fieldObj.name).join('.');
context.reportError(
- `Cannot reference Input Object "${fieldType.name}" within itself through a series of non-null fields: "${pathStr}".`,
+ `Cannot reference Input Object "${fieldType}" within itself through a series of non-null fields: "${pathStr}".`,
cyclePath.map((fieldObj) => fieldObj.astNode),
);
}
diff --git a/src/utilities/__tests__/buildClientSchema-test.ts b/src/utilities/__tests__/buildClientSchema-test.ts
index 818198bf7bc..b65b8cfcdea 100644
--- a/src/utilities/__tests__/buildClientSchema-test.ts
+++ b/src/utilities/__tests__/buildClientSchema-test.ts
@@ -377,32 +377,38 @@ describe('Type System: build schema from introspection', () => {
// Client types do not get server-only values, so `value` mirrors `name`,
// rather than using the integers defined in the "server" schema.
- expect(clientFoodEnum.getValues()).to.deep.equal([
- {
- name: 'VEGETABLES',
- description: 'Foods that are vegetables.',
- value: 'VEGETABLES',
- deprecationReason: null,
- extensions: {},
- astNode: undefined,
- },
- {
- name: 'FRUITS',
- description: null,
- value: 'FRUITS',
- deprecationReason: null,
- extensions: {},
- astNode: undefined,
- },
- {
- name: 'OILS',
- description: null,
- value: 'OILS',
- deprecationReason: 'Too fatty',
- extensions: {},
- astNode: undefined,
- },
- ]);
+ const values = clientFoodEnum.getValues();
+ expect(values).to.have.lengthOf(3);
+
+ expect(values[0]).to.deep.include({
+ coordinate: 'Food.VEGETABLES',
+ name: 'VEGETABLES',
+ description: 'Foods that are vegetables.',
+ value: 'VEGETABLES',
+ deprecationReason: null,
+ extensions: {},
+ astNode: undefined,
+ });
+
+ expect(values[1]).to.deep.include({
+ coordinate: 'Food.FRUITS',
+ name: 'FRUITS',
+ description: null,
+ value: 'FRUITS',
+ deprecationReason: null,
+ extensions: {},
+ astNode: undefined,
+ });
+
+ expect(values[2]).to.deep.include({
+ coordinate: 'Food.OILS',
+ name: 'OILS',
+ description: null,
+ value: 'OILS',
+ deprecationReason: 'Too fatty',
+ extensions: {},
+ astNode: undefined,
+ });
});
it('builds a schema with an input object', () => {
diff --git a/src/utilities/__tests__/findBreakingChanges-test.ts b/src/utilities/__tests__/findBreakingChanges-test.ts
index 5d92522fe32..52a80971a04 100644
--- a/src/utilities/__tests__/findBreakingChanges-test.ts
+++ b/src/utilities/__tests__/findBreakingChanges-test.ts
@@ -57,7 +57,7 @@ describe('findBreakingChanges', () => {
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Query.foo changed type from Float to String.',
+ description: 'Field Query.foo changed type from Float to String.',
},
]);
expect(findBreakingChanges(oldSchema, oldSchema)).to.deep.equal([]);
@@ -149,55 +149,56 @@ describe('findBreakingChanges', () => {
expect(changes).to.deep.equal([
{
type: BreakingChangeType.FIELD_REMOVED,
- description: 'Type1.field2 was removed.',
+ description: 'Field Type1.field2 was removed.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field3 changed type from String to Boolean.',
+ description: 'Field Type1.field3 changed type from String to Boolean.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field4 changed type from TypeA to TypeB.',
+ description: 'Field Type1.field4 changed type from TypeA to TypeB.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field6 changed type from String to [String].',
+ description: 'Field Type1.field6 changed type from String to [String].',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field7 changed type from [String] to String.',
+ description: 'Field Type1.field7 changed type from [String] to String.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field9 changed type from Int! to Int.',
+ description: 'Field Type1.field9 changed type from Int! to Int.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field10 changed type from [Int]! to [Int].',
+ description: 'Field Type1.field10 changed type from [Int]! to [Int].',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field11 changed type from Int to [Int]!.',
+ description: 'Field Type1.field11 changed type from Int to [Int]!.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field13 changed type from [Int!] to [Int].',
+ description: 'Field Type1.field13 changed type from [Int!] to [Int].',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field14 changed type from [Int] to [[Int]].',
+ description: 'Field Type1.field14 changed type from [Int] to [[Int]].',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field15 changed type from [[Int]] to [Int].',
+ description: 'Field Type1.field15 changed type from [[Int]] to [Int].',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field16 changed type from Int! to [Int]!.',
+ description: 'Field Type1.field16 changed type from Int! to [Int]!.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description: 'Type1.field18 changed type from [[Int!]!] to [[Int!]].',
+ description:
+ 'Field Type1.field18 changed type from [[Int!]!] to [[Int!]].',
},
]);
});
@@ -310,8 +311,7 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.REQUIRED_INPUT_FIELD_ADDED,
- description:
- 'A required field requiredField on input type InputType1 was added.',
+ description: 'A required field InputType1.requiredField was added.',
},
]);
});
@@ -360,7 +360,7 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM,
- description: 'VALUE1 was removed from enum type EnumType1.',
+ description: 'Enum value EnumType1.VALUE1 was removed.',
},
]);
});
@@ -389,15 +389,15 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.ARG_REMOVED,
- description: 'Interface1.field1 arg arg1 was removed.',
+ description: 'Argument Interface1.field1(arg1:) was removed.',
},
{
type: BreakingChangeType.ARG_REMOVED,
- description: 'Interface1.field1 arg objectArg was removed.',
+ description: 'Argument Interface1.field1(objectArg:) was removed.',
},
{
type: BreakingChangeType.ARG_REMOVED,
- description: 'Type1.field1 arg name was removed.',
+ description: 'Argument Type1.field1(name:) was removed.',
},
]);
});
@@ -451,62 +451,62 @@ describe('findBreakingChanges', () => {
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg1 has changed type from String to Int.',
+ 'Argument Type1.field1(arg1:) has changed type from String to Int.',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg2 has changed type from String to [String].',
+ 'Argument Type1.field1(arg2:) has changed type from String to [String].',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg3 has changed type from [String] to String.',
+ 'Argument Type1.field1(arg3:) has changed type from [String] to String.',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg4 has changed type from String to String!.',
+ 'Argument Type1.field1(arg4:) has changed type from String to String!.',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg5 has changed type from String! to Int.',
+ 'Argument Type1.field1(arg5:) has changed type from String! to Int.',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg6 has changed type from String! to Int!.',
+ 'Argument Type1.field1(arg6:) has changed type from String! to Int!.',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg8 has changed type from Int to [Int]!.',
+ 'Argument Type1.field1(arg8:) has changed type from Int to [Int]!.',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg9 has changed type from [Int] to [Int!].',
+ 'Argument Type1.field1(arg9:) has changed type from [Int] to [Int!].',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg11 has changed type from [Int] to [[Int]].',
+ 'Argument Type1.field1(arg11:) has changed type from [Int] to [[Int]].',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg12 has changed type from [[Int]] to [Int].',
+ 'Argument Type1.field1(arg12:) has changed type from [[Int]] to [Int].',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg13 has changed type from Int! to [Int]!.',
+ 'Argument Type1.field1(arg13:) has changed type from Int! to [Int]!.',
},
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'Type1.field1 arg arg15 has changed type from [[Int]!] to [[Int!]!].',
+ 'Argument Type1.field1(arg15:) has changed type from [[Int]!] to [[Int!]!].',
},
]);
});
@@ -532,7 +532,8 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.REQUIRED_ARG_ADDED,
- description: 'A required arg newRequiredArg on Type1.field1 was added.',
+ description:
+ 'A required argument Type1.field1(newRequiredArg:) was added.',
},
]);
});
@@ -721,12 +722,11 @@ describe('findBreakingChanges', () => {
{
type: BreakingChangeType.ARG_CHANGED_KIND,
description:
- 'ArgThatChanges.field1 arg id has changed type from Float to String.',
+ 'Argument ArgThatChanges.field1(id:) has changed type from Float to String.',
},
{
type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM,
- description:
- 'VALUE0 was removed from enum type EnumTypeThatLosesAValue.',
+ description: 'Enum value EnumTypeThatLosesAValue.VALUE0 was removed.',
},
{
type: BreakingChangeType.IMPLEMENTED_INTERFACE_REMOVED,
@@ -745,34 +745,35 @@ describe('findBreakingChanges', () => {
},
{
type: BreakingChangeType.FIELD_REMOVED,
- description: 'TypeThatHasBreakingFieldChanges.field1 was removed.',
+ description:
+ 'Field TypeThatHasBreakingFieldChanges.field1 was removed.',
},
{
type: BreakingChangeType.FIELD_CHANGED_KIND,
description:
- 'TypeThatHasBreakingFieldChanges.field2 changed type from String to Boolean.',
+ 'Field TypeThatHasBreakingFieldChanges.field2 changed type from String to Boolean.',
},
{
type: BreakingChangeType.DIRECTIVE_REMOVED,
- description: 'DirectiveThatIsRemoved was removed.',
+ description: 'Directive @DirectiveThatIsRemoved was removed.',
},
{
type: BreakingChangeType.DIRECTIVE_ARG_REMOVED,
- description: 'arg1 was removed from DirectiveThatRemovesArg.',
+ description: 'Argument @DirectiveThatRemovesArg(arg1:) was removed.',
},
{
type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED,
description:
- 'A required arg arg1 on directive NonNullDirectiveAdded was added.',
+ 'A required argument @NonNullDirectiveAdded(arg1:) was added.',
},
{
type: BreakingChangeType.DIRECTIVE_REPEATABLE_REMOVED,
description:
- 'Repeatable flag was removed from DirectiveThatWasRepeatable.',
+ 'Repeatable flag was removed from @DirectiveThatWasRepeatable.',
},
{
type: BreakingChangeType.DIRECTIVE_LOCATION_REMOVED,
- description: 'QUERY was removed from DirectiveName.',
+ description: 'QUERY was removed from @DirectiveName.',
},
]);
});
@@ -790,7 +791,7 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.DIRECTIVE_REMOVED,
- description: 'DirectiveThatIsRemoved was removed.',
+ description: 'Directive @DirectiveThatIsRemoved was removed.',
},
]);
});
@@ -810,7 +811,7 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.DIRECTIVE_REMOVED,
- description: `${GraphQLDeprecatedDirective.name} was removed.`,
+ description: `Directive ${GraphQLDeprecatedDirective} was removed.`,
},
]);
});
@@ -827,7 +828,7 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.DIRECTIVE_ARG_REMOVED,
- description: 'arg1 was removed from DirectiveWithArg.',
+ description: 'Argument @DirectiveWithArg(arg1:) was removed.',
},
]);
});
@@ -849,7 +850,7 @@ describe('findBreakingChanges', () => {
{
type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED,
description:
- 'A required arg newRequiredArg on directive DirectiveName was added.',
+ 'A required argument @DirectiveName(newRequiredArg:) was added.',
},
]);
});
@@ -866,7 +867,7 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.DIRECTIVE_REPEATABLE_REMOVED,
- description: 'Repeatable flag was removed from DirectiveName.',
+ description: 'Repeatable flag was removed from @DirectiveName.',
},
]);
});
@@ -883,7 +884,7 @@ describe('findBreakingChanges', () => {
expect(findBreakingChanges(oldSchema, newSchema)).to.deep.equal([
{
type: BreakingChangeType.DIRECTIVE_LOCATION_REMOVED,
- description: 'QUERY was removed from DirectiveName.',
+ description: 'QUERY was removed from @DirectiveName.',
},
]);
});
@@ -943,27 +944,27 @@ describe('findDangerousChanges', () => {
{
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
description:
- 'Type1.field1 arg withDefaultValue defaultValue was removed.',
+ 'Type1.field1(withDefaultValue:) defaultValue was removed.',
},
{
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
description:
- 'Type1.field1 arg stringArg has changed defaultValue from "test" to "Test".',
+ 'Type1.field1(stringArg:) has changed defaultValue from "test" to "Test".',
},
{
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
description:
- 'Type1.field1 arg emptyArray has changed defaultValue from [] to [7].',
+ 'Type1.field1(emptyArray:) has changed defaultValue from [] to [7].',
},
{
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
description:
- 'Type1.field1 arg valueArray has changed defaultValue from [["a", "b"], ["c"]] to [["b", "a"], ["d"]].',
+ 'Type1.field1(valueArray:) has changed defaultValue from [["a", "b"], ["c"]] to [["b", "a"], ["d"]].',
},
{
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
description:
- 'Type1.field1 arg complexObject has changed defaultValue from { innerInputArray: [{ arrayField: [1, 2, 3] }] } to { innerInputArray: [{ arrayField: [3, 2, 1] }] }.',
+ 'Type1.field1(complexObject:) has changed defaultValue from { innerInputArray: [{ arrayField: [1, 2, 3] }] } to { innerInputArray: [{ arrayField: [3, 2, 1] }] }.',
},
]);
});
@@ -1051,7 +1052,7 @@ describe('findDangerousChanges', () => {
expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([
{
type: DangerousChangeType.VALUE_ADDED_TO_ENUM,
- description: 'VALUE2 was added to enum type EnumType1.',
+ description: 'Enum value EnumType1.VALUE2 was added.',
},
]);
});
@@ -1143,8 +1144,7 @@ describe('findDangerousChanges', () => {
expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([
{
type: DangerousChangeType.OPTIONAL_INPUT_FIELD_ADDED,
- description:
- 'An optional field field2 on input type InputType1 was added.',
+ description: 'An optional field InputType1.field2 was added.',
},
]);
});
@@ -1189,12 +1189,12 @@ describe('findDangerousChanges', () => {
expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([
{
type: DangerousChangeType.VALUE_ADDED_TO_ENUM,
- description: 'VALUE2 was added to enum type EnumType1.',
+ description: 'Enum value EnumType1.VALUE2 was added.',
},
{
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
description:
- 'Type1.field1 arg argThatChangesDefaultValue has changed defaultValue from "test" to "Test".',
+ 'Type1.field1(argThatChangesDefaultValue:) has changed defaultValue from "test" to "Test".',
},
{
type: DangerousChangeType.IMPLEMENTED_INTERFACE_ADDED,
@@ -1225,7 +1225,7 @@ describe('findDangerousChanges', () => {
expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([
{
type: DangerousChangeType.OPTIONAL_ARG_ADDED,
- description: 'An optional arg arg2 on Type1.field1 was added.',
+ description: 'An optional argument Type1.field1(arg2:) was added.',
},
]);
});
diff --git a/src/utilities/findBreakingChanges.ts b/src/utilities/findBreakingChanges.ts
index 793d29bc836..6b693046291 100644
--- a/src/utilities/findBreakingChanges.ts
+++ b/src/utilities/findBreakingChanges.ts
@@ -124,7 +124,7 @@ function findDirectiveChanges(
for (const oldDirective of directivesDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.DIRECTIVE_REMOVED,
- description: `${oldDirective.name} was removed.`,
+ description: `Directive ${oldDirective} was removed.`,
});
}
@@ -135,7 +135,7 @@ function findDirectiveChanges(
if (isRequiredArgument(newArg)) {
schemaChanges.push({
type: BreakingChangeType.REQUIRED_DIRECTIVE_ARG_ADDED,
- description: `A required arg ${newArg.name} on directive ${oldDirective.name} was added.`,
+ description: `A required argument ${newArg} was added.`,
});
}
}
@@ -143,14 +143,14 @@ function findDirectiveChanges(
for (const oldArg of argsDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.DIRECTIVE_ARG_REMOVED,
- description: `${oldArg.name} was removed from ${oldDirective.name}.`,
+ description: `Argument ${oldArg} was removed.`,
});
}
if (oldDirective.isRepeatable && !newDirective.isRepeatable) {
schemaChanges.push({
type: BreakingChangeType.DIRECTIVE_REPEATABLE_REMOVED,
- description: `Repeatable flag was removed from ${oldDirective.name}.`,
+ description: `Repeatable flag was removed from ${oldDirective}.`,
});
}
@@ -158,7 +158,7 @@ function findDirectiveChanges(
if (!newDirective.locations.includes(location)) {
schemaChanges.push({
type: BreakingChangeType.DIRECTIVE_LOCATION_REMOVED,
- description: `${location} was removed from ${oldDirective.name}.`,
+ description: `${location} was removed from ${oldDirective}.`,
});
}
}
@@ -182,8 +182,8 @@ function findTypeChanges(
schemaChanges.push({
type: BreakingChangeType.TYPE_REMOVED,
description: isSpecifiedScalarType(oldType)
- ? `Standard scalar ${oldType.name} was removed because it is not referenced anymore.`
- : `${oldType.name} was removed.`,
+ ? `Standard scalar ${oldType} was removed because it is not referenced anymore.`
+ : `${oldType} was removed.`,
});
}
@@ -207,9 +207,9 @@ function findTypeChanges(
} else if (oldType.constructor !== newType.constructor) {
schemaChanges.push({
type: BreakingChangeType.TYPE_CHANGED_KIND,
- description:
- `${oldType.name} changed from ` +
- `${typeKindName(oldType)} to ${typeKindName(newType)}.`,
+ description: `${oldType} changed from ${typeKindName(
+ oldType,
+ )} to ${typeKindName(newType)}.`,
});
}
}
@@ -231,12 +231,12 @@ function findInputObjectTypeChanges(
if (isRequiredInputField(newField)) {
schemaChanges.push({
type: BreakingChangeType.REQUIRED_INPUT_FIELD_ADDED,
- description: `A required field ${newField.name} on input type ${oldType.name} was added.`,
+ description: `A required field ${newField} was added.`,
});
} else {
schemaChanges.push({
type: DangerousChangeType.OPTIONAL_INPUT_FIELD_ADDED,
- description: `An optional field ${newField.name} on input type ${oldType.name} was added.`,
+ description: `An optional field ${newField} was added.`,
});
}
}
@@ -244,7 +244,7 @@ function findInputObjectTypeChanges(
for (const oldField of fieldsDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.FIELD_REMOVED,
- description: `${oldType.name}.${oldField.name} was removed.`,
+ description: `${oldField} was removed.`,
});
}
@@ -256,9 +256,7 @@ function findInputObjectTypeChanges(
if (!isSafe) {
schemaChanges.push({
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description:
- `${oldType.name}.${oldField.name} changed type from ` +
- `${String(oldField.type)} to ${String(newField.type)}.`,
+ description: `${newField} changed type from ${oldField.type} to ${newField.type}.`,
});
}
}
@@ -276,14 +274,14 @@ function findUnionTypeChanges(
for (const newPossibleType of possibleTypesDiff.added) {
schemaChanges.push({
type: DangerousChangeType.TYPE_ADDED_TO_UNION,
- description: `${newPossibleType.name} was added to union type ${oldType.name}.`,
+ description: `${newPossibleType} was added to union type ${oldType}.`,
});
}
for (const oldPossibleType of possibleTypesDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.TYPE_REMOVED_FROM_UNION,
- description: `${oldPossibleType.name} was removed from union type ${oldType.name}.`,
+ description: `${oldPossibleType} was removed from union type ${oldType}.`,
});
}
@@ -300,14 +298,14 @@ function findEnumTypeChanges(
for (const newValue of valuesDiff.added) {
schemaChanges.push({
type: DangerousChangeType.VALUE_ADDED_TO_ENUM,
- description: `${newValue.name} was added to enum type ${oldType.name}.`,
+ description: `Enum value ${newValue} was added.`,
});
}
for (const oldValue of valuesDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM,
- description: `${oldValue.name} was removed from enum type ${oldType.name}.`,
+ description: `Enum value ${oldValue} was removed.`,
});
}
@@ -324,14 +322,14 @@ function findImplementedInterfacesChanges(
for (const newInterface of interfacesDiff.added) {
schemaChanges.push({
type: DangerousChangeType.IMPLEMENTED_INTERFACE_ADDED,
- description: `${newInterface.name} added to interfaces implemented by ${oldType.name}.`,
+ description: `${newInterface} added to interfaces implemented by ${oldType}.`,
});
}
for (const oldInterface of interfacesDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.IMPLEMENTED_INTERFACE_REMOVED,
- description: `${oldType.name} no longer implements interface ${oldInterface.name}.`,
+ description: `${oldType} no longer implements interface ${oldInterface}.`,
});
}
@@ -351,12 +349,12 @@ function findFieldChanges(
for (const oldField of fieldsDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.FIELD_REMOVED,
- description: `${oldType.name}.${oldField.name} was removed.`,
+ description: `Field ${oldField} was removed.`,
});
}
for (const [oldField, newField] of fieldsDiff.persisted) {
- schemaChanges.push(...findArgChanges(oldType, oldField, newField));
+ schemaChanges.push(...findArgChanges(oldField, newField));
const isSafe = isChangeSafeForObjectOrInterfaceField(
oldField.type,
@@ -365,9 +363,7 @@ function findFieldChanges(
if (!isSafe) {
schemaChanges.push({
type: BreakingChangeType.FIELD_CHANGED_KIND,
- description:
- `${oldType.name}.${oldField.name} changed type from ` +
- `${String(oldField.type)} to ${String(newField.type)}.`,
+ description: `Field ${newField} changed type from ${oldField.type} to ${newField.type}.`,
});
}
}
@@ -376,7 +372,6 @@ function findFieldChanges(
}
function findArgChanges(
- oldType: GraphQLObjectType | GraphQLInterfaceType,
oldField: GraphQLField,
newField: GraphQLField,
): Array {
@@ -386,7 +381,7 @@ function findArgChanges(
for (const oldArg of argsDiff.removed) {
schemaChanges.push({
type: BreakingChangeType.ARG_REMOVED,
- description: `${oldType.name}.${oldField.name} arg ${oldArg.name} was removed.`,
+ description: `Argument ${oldArg} was removed.`,
});
}
@@ -398,15 +393,13 @@ function findArgChanges(
if (!isSafe) {
schemaChanges.push({
type: BreakingChangeType.ARG_CHANGED_KIND,
- description:
- `${oldType.name}.${oldField.name} arg ${oldArg.name} has changed type from ` +
- `${String(oldArg.type)} to ${String(newArg.type)}.`,
+ description: `Argument ${newArg} has changed type from ${oldArg.type} to ${newArg.type}.`,
});
} else if (oldArg.defaultValue !== undefined) {
if (newArg.defaultValue === undefined) {
schemaChanges.push({
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
- description: `${oldType.name}.${oldField.name} arg ${oldArg.name} defaultValue was removed.`,
+ description: `${oldArg} defaultValue was removed.`,
});
} else {
// Since we looking only for client's observable changes we should
@@ -418,7 +411,7 @@ function findArgChanges(
if (oldValueStr !== newValueStr) {
schemaChanges.push({
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
- description: `${oldType.name}.${oldField.name} arg ${oldArg.name} has changed defaultValue from ${oldValueStr} to ${newValueStr}.`,
+ description: `${oldArg} has changed defaultValue from ${oldValueStr} to ${newValueStr}.`,
});
}
}
@@ -429,12 +422,12 @@ function findArgChanges(
if (isRequiredArgument(newArg)) {
schemaChanges.push({
type: BreakingChangeType.REQUIRED_ARG_ADDED,
- description: `A required arg ${newArg.name} on ${oldType.name}.${oldField.name} was added.`,
+ description: `A required argument ${newArg} was added.`,
});
} else {
schemaChanges.push({
type: DangerousChangeType.OPTIONAL_ARG_ADDED,
- description: `An optional arg ${newArg.name} on ${oldType.name}.${oldField.name} was added.`,
+ description: `An optional argument ${newArg} was added.`,
});
}
}
diff --git a/src/validation/__tests__/NoDeprecatedCustomRule-test.ts b/src/validation/__tests__/NoDeprecatedCustomRule-test.ts
index 96823684fc0..9c0e50fc74f 100644
--- a/src/validation/__tests__/NoDeprecatedCustomRule-test.ts
+++ b/src/validation/__tests__/NoDeprecatedCustomRule-test.ts
@@ -106,7 +106,7 @@ describe('Validate: no deprecated', () => {
`).toDeepEqual([
{
message:
- 'Field "Query.someField" argument "deprecatedArg" is deprecated. Some arg reason.',
+ 'The argument Query.someField(deprecatedArg:) is deprecated. Some arg reason.',
locations: [{ line: 3, column: 21 }],
},
]);
@@ -150,7 +150,7 @@ describe('Validate: no deprecated', () => {
`).toDeepEqual([
{
message:
- 'Directive "@someDirective" argument "deprecatedArg" is deprecated. Some arg reason.',
+ 'The argument @someDirective(deprecatedArg:) is deprecated. Some arg reason.',
locations: [{ line: 3, column: 36 }],
},
]);
@@ -255,7 +255,7 @@ describe('Validate: no deprecated', () => {
it('reports error when a deprecated enum value is used', () => {
const message =
- 'The enum value "EnumType.DEPRECATED_VALUE" is deprecated. Some enum reason.';
+ 'The enum value EnumType.DEPRECATED_VALUE is deprecated. Some enum reason.';
expectErrors(`
query (
diff --git a/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts b/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts
index 6f0d223c15e..f9d2a956bd3 100644
--- a/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts
+++ b/src/validation/__tests__/ProvidedRequiredArgumentsRule-test.ts
@@ -168,7 +168,7 @@ describe('Validate: Provided required arguments', () => {
`).toDeepEqual([
{
message:
- 'Field "multipleReqs" argument "req1" of type "Int!" is required, but it was not provided.',
+ 'Argument ComplicatedArgs.multipleReqs(req1:) of type "Int!" is required, but it was not provided.',
locations: [{ line: 4, column: 13 }],
},
]);
@@ -184,12 +184,12 @@ describe('Validate: Provided required arguments', () => {
`).toDeepEqual([
{
message:
- 'Field "multipleReqs" argument "req1" of type "Int!" is required, but it was not provided.',
+ 'Argument ComplicatedArgs.multipleReqs(req1:) of type "Int!" is required, but it was not provided.',
locations: [{ line: 4, column: 13 }],
},
{
message:
- 'Field "multipleReqs" argument "req2" of type "Int!" is required, but it was not provided.',
+ 'Argument ComplicatedArgs.multipleReqs(req2:) of type "Int!" is required, but it was not provided.',
locations: [{ line: 4, column: 13 }],
},
]);
@@ -205,7 +205,7 @@ describe('Validate: Provided required arguments', () => {
`).toDeepEqual([
{
message:
- 'Field "multipleReqs" argument "req2" of type "Int!" is required, but it was not provided.',
+ 'Argument ComplicatedArgs.multipleReqs(req2:) of type "Int!" is required, but it was not provided.',
locations: [{ line: 4, column: 13 }],
},
]);
@@ -244,12 +244,12 @@ describe('Validate: Provided required arguments', () => {
`).toDeepEqual([
{
message:
- 'Directive "@include" argument "if" of type "Boolean!" is required, but it was not provided.',
+ 'Argument @include(if:) of type "Boolean!" is required, but it was not provided.',
locations: [{ line: 3, column: 15 }],
},
{
message:
- 'Directive "@skip" argument "if" of type "Boolean!" is required, but it was not provided.',
+ 'Argument @skip(if:) of type "Boolean!" is required, but it was not provided.',
locations: [{ line: 4, column: 18 }],
},
]);
@@ -277,7 +277,7 @@ describe('Validate: Provided required arguments', () => {
`).toDeepEqual([
{
message:
- 'Directive "@test" argument "arg" of type "String!" is required, but it was not provided.',
+ 'Argument @test(arg:) of type "String!" is required, but it was not provided.',
locations: [{ line: 3, column: 23 }],
},
]);
@@ -291,7 +291,7 @@ describe('Validate: Provided required arguments', () => {
`).toDeepEqual([
{
message:
- 'Directive "@include" argument "if" of type "Boolean!" is required, but it was not provided.',
+ 'Argument @include(if:) of type "Boolean!" is required, but it was not provided.',
locations: [{ line: 3, column: 23 }],
},
]);
@@ -306,7 +306,7 @@ describe('Validate: Provided required arguments', () => {
`).toDeepEqual([
{
message:
- 'Directive "@deprecated" argument "reason" of type "String!" is required, but it was not provided.',
+ 'Argument @deprecated(reason:) of type "String!" is required, but it was not provided.',
locations: [{ line: 3, column: 23 }],
},
]);
@@ -328,7 +328,7 @@ describe('Validate: Provided required arguments', () => {
).toDeepEqual([
{
message:
- 'Directive "@test" argument "arg" of type "String!" is required, but it was not provided.',
+ 'Argument @test(arg:) of type "String!" is required, but it was not provided.',
locations: [{ line: 4, column: 30 }],
},
]);
@@ -350,7 +350,7 @@ describe('Validate: Provided required arguments', () => {
).toDeepEqual([
{
message:
- 'Directive "@test" argument "arg" of type "String!" is required, but it was not provided.',
+ 'Argument @test(arg:) of type "String!" is required, but it was not provided.',
locations: [{ line: 2, column: 29 }],
},
]);
diff --git a/src/validation/rules/FieldsOnCorrectTypeRule.ts b/src/validation/rules/FieldsOnCorrectTypeRule.ts
index 5d61e08b032..c6fce9e89b5 100644
--- a/src/validation/rules/FieldsOnCorrectTypeRule.ts
+++ b/src/validation/rules/FieldsOnCorrectTypeRule.ts
@@ -56,7 +56,7 @@ export function FieldsOnCorrectTypeRule(
// Report an error, including helpful suggestions.
context.reportError(
new GraphQLError(
- `Cannot query field "${fieldName}" on type "${type.name}".` +
+ `Cannot query field "${fieldName}" on type "${type}".` +
suggestion,
{ nodes: node },
),
diff --git a/src/validation/rules/KnownArgumentNamesRule.ts b/src/validation/rules/KnownArgumentNamesRule.ts
index 2f093487783..9dd9a80a6f5 100644
--- a/src/validation/rules/KnownArgumentNamesRule.ts
+++ b/src/validation/rules/KnownArgumentNamesRule.ts
@@ -29,15 +29,14 @@ export function KnownArgumentNamesRule(context: ValidationContext): ASTVisitor {
Argument(argNode) {
const argDef = context.getArgument();
const fieldDef = context.getFieldDef();
- const parentType = context.getParentType();
- if (!argDef && fieldDef && parentType) {
+ if (!argDef && fieldDef) {
const argName = argNode.name.value;
const knownArgsNames = fieldDef.args.map((arg) => arg.name);
const suggestions = suggestionList(argName, knownArgsNames);
context.reportError(
new GraphQLError(
- `Unknown argument "${argName}" on field "${parentType.name}.${fieldDef.name}".` +
+ `Unknown argument "${argName}" on field "${fieldDef}".` +
didYouMean(suggestions),
{ nodes: argNode },
),
diff --git a/src/validation/rules/ProvidedRequiredArgumentsRule.ts b/src/validation/rules/ProvidedRequiredArgumentsRule.ts
index 72d104b852f..df61349d2b3 100644
--- a/src/validation/rules/ProvidedRequiredArgumentsRule.ts
+++ b/src/validation/rules/ProvidedRequiredArgumentsRule.ts
@@ -43,10 +43,9 @@ export function ProvidedRequiredArgumentsRule(
);
for (const argDef of fieldDef.args) {
if (!providedArgs.has(argDef.name) && isRequiredArgument(argDef)) {
- const argTypeStr = inspect(argDef.type);
context.reportError(
new GraphQLError(
- `Field "${fieldDef.name}" argument "${argDef.name}" of type "${argTypeStr}" is required, but it was not provided.`,
+ `Argument ${argDef} of type "${argDef.type}" is required, but it was not provided.`,
{ nodes: fieldNode },
),
);
@@ -115,7 +114,7 @@ export function ProvidedRequiredArgumentsOnDirectivesRule(
: print(argDef.type);
context.reportError(
new GraphQLError(
- `Directive "@${directiveName}" argument "${argName}" of type "${argType}" is required, but it was not provided.`,
+ `Argument @${directiveName}(${argName}:) of type "${argType}" is required, but it was not provided.`,
{ nodes: directiveNode },
),
);
diff --git a/src/validation/rules/ValuesOfCorrectTypeRule.ts b/src/validation/rules/ValuesOfCorrectTypeRule.ts
index 3b9a1ee645b..71d06e059dd 100644
--- a/src/validation/rules/ValuesOfCorrectTypeRule.ts
+++ b/src/validation/rules/ValuesOfCorrectTypeRule.ts
@@ -1,5 +1,4 @@
import { didYouMean } from '../../jsutils/didYouMean.js';
-import { inspect } from '../../jsutils/inspect.js';
import { suggestionList } from '../../jsutils/suggestionList.js';
import { GraphQLError } from '../../error/GraphQLError.js';
@@ -71,10 +70,9 @@ export function ValuesOfCorrectTypeRule(
for (const fieldDef of Object.values(type.getFields())) {
const fieldNode = fieldNodeMap.get(fieldDef.name);
if (!fieldNode && isRequiredInputField(fieldDef)) {
- const typeStr = inspect(fieldDef.type);
context.reportError(
new GraphQLError(
- `Field "${type.name}.${fieldDef.name}" of required type "${typeStr}" was not provided.`,
+ `Field "${fieldDef}" of required type "${fieldDef.type}" was not provided.`,
{ nodes: node },
),
);
@@ -101,7 +99,7 @@ export function ValuesOfCorrectTypeRule(
);
context.reportError(
new GraphQLError(
- `Field "${node.name.value}" is not defined by type "${parentType.name}".` +
+ `Field "${node.name.value}" is not defined by type "${parentType}".` +
didYouMean(suggestions),
{ nodes: node },
),
@@ -113,7 +111,7 @@ export function ValuesOfCorrectTypeRule(
if (isNonNullType(type)) {
context.reportError(
new GraphQLError(
- `Expected value of type "${inspect(type)}", found ${print(node)}.`,
+ `Expected value of type "${type}", found ${print(node)}.`,
{ nodes: node },
),
);
@@ -141,10 +139,9 @@ function isValidValueNode(context: ValidationContext, node: ValueNode): void {
const type = getNamedType(locationType);
if (!isLeafType(type)) {
- const typeStr = inspect(locationType);
context.reportError(
new GraphQLError(
- `Expected value of type "${typeStr}", found ${print(node)}.`,
+ `Expected value of type "${locationType}", found ${print(node)}.`,
{ nodes: node },
),
);
@@ -156,22 +153,20 @@ function isValidValueNode(context: ValidationContext, node: ValueNode): void {
try {
const parseResult = type.parseLiteral(node, undefined /* variables */);
if (parseResult === undefined) {
- const typeStr = inspect(locationType);
context.reportError(
new GraphQLError(
- `Expected value of type "${typeStr}", found ${print(node)}.`,
+ `Expected value of type "${locationType}", found ${print(node)}.`,
{ nodes: node },
),
);
}
} catch (error) {
- const typeStr = inspect(locationType);
if (error instanceof GraphQLError) {
context.reportError(error);
} else {
context.reportError(
new GraphQLError(
- `Expected value of type "${typeStr}", found ${print(node)}; ` +
+ `Expected value of type "${locationType}", found ${print(node)}; ` +
error.message,
{ nodes: node, originalError: error },
),
diff --git a/src/validation/rules/VariablesInAllowedPositionRule.ts b/src/validation/rules/VariablesInAllowedPositionRule.ts
index e662ba443c1..f324a3daa4f 100644
--- a/src/validation/rules/VariablesInAllowedPositionRule.ts
+++ b/src/validation/rules/VariablesInAllowedPositionRule.ts
@@ -1,4 +1,3 @@
-import { inspect } from '../../jsutils/inspect.js';
import type { Maybe } from '../../jsutils/Maybe.js';
import { GraphQLError } from '../../error/GraphQLError.js';
@@ -57,11 +56,9 @@ export function VariablesInAllowedPositionRule(
defaultValue,
)
) {
- const varTypeStr = inspect(varType);
- const typeStr = inspect(type);
context.reportError(
new GraphQLError(
- `Variable "$${varName}" of type "${varTypeStr}" used in position expecting type "${typeStr}".`,
+ `Variable "$${varName}" of type "${varType}" used in position expecting type "${type}".`,
{ nodes: [varDef, node] },
),
);
diff --git a/src/validation/rules/custom/NoDeprecatedCustomRule.ts b/src/validation/rules/custom/NoDeprecatedCustomRule.ts
index 375373eb1d9..0a42dae302b 100644
--- a/src/validation/rules/custom/NoDeprecatedCustomRule.ts
+++ b/src/validation/rules/custom/NoDeprecatedCustomRule.ts
@@ -1,5 +1,3 @@
-import { invariant } from '../../../jsutils/invariant.js';
-
import { GraphQLError } from '../../../error/GraphQLError.js';
import type { ASTVisitor } from '../../../language/visitor.js';
@@ -24,11 +22,9 @@ export function NoDeprecatedCustomRule(context: ValidationContext): ASTVisitor {
const fieldDef = context.getFieldDef();
const deprecationReason = fieldDef?.deprecationReason;
if (fieldDef && deprecationReason != null) {
- const parentType = context.getParentType();
- invariant(parentType != null);
context.reportError(
new GraphQLError(
- `The field ${parentType.name}.${fieldDef.name} is deprecated. ${deprecationReason}`,
+ `The field ${fieldDef} is deprecated. ${deprecationReason}`,
{ nodes: node },
),
);
@@ -38,25 +34,12 @@ export function NoDeprecatedCustomRule(context: ValidationContext): ASTVisitor {
const argDef = context.getArgument();
const deprecationReason = argDef?.deprecationReason;
if (argDef && deprecationReason != null) {
- const directiveDef = context.getDirective();
- if (directiveDef != null) {
- context.reportError(
- new GraphQLError(
- `Directive "@${directiveDef.name}" argument "${argDef.name}" is deprecated. ${deprecationReason}`,
- { nodes: node },
- ),
- );
- } else {
- const parentType = context.getParentType();
- const fieldDef = context.getFieldDef();
- invariant(parentType != null && fieldDef != null);
- context.reportError(
- new GraphQLError(
- `Field "${parentType.name}.${fieldDef.name}" argument "${argDef.name}" is deprecated. ${deprecationReason}`,
- { nodes: node },
- ),
- );
- }
+ context.reportError(
+ new GraphQLError(
+ `The argument ${argDef} is deprecated. ${deprecationReason}`,
+ { nodes: node },
+ ),
+ );
}
},
ObjectField(node) {
@@ -67,7 +50,7 @@ export function NoDeprecatedCustomRule(context: ValidationContext): ASTVisitor {
if (deprecationReason != null) {
context.reportError(
new GraphQLError(
- `The input field ${inputObjectDef.name}.${inputFieldDef.name} is deprecated. ${deprecationReason}`,
+ `The input field ${inputFieldDef} is deprecated. ${deprecationReason}`,
{ nodes: node },
),
);
@@ -78,11 +61,9 @@ export function NoDeprecatedCustomRule(context: ValidationContext): ASTVisitor {
const enumValueDef = context.getEnumValue();
const deprecationReason = enumValueDef?.deprecationReason;
if (enumValueDef && deprecationReason != null) {
- const enumTypeDef = getNamedType(context.getInputType());
- invariant(enumTypeDef != null);
context.reportError(
new GraphQLError(
- `The enum value "${enumTypeDef.name}.${enumValueDef.name}" is deprecated. ${deprecationReason}`,
+ `The enum value ${enumValueDef} is deprecated. ${deprecationReason}`,
{ nodes: node },
),
);