Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add KnownOperationTypes rule #3601

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ export {
KnownArgumentNamesRule,
KnownDirectivesRule,
KnownFragmentNamesRule,
KnownOperationTypesRule,
KnownTypeNamesRule,
LoneAnonymousOperationRule,
NoFragmentCyclesRule,
Expand Down
60 changes: 60 additions & 0 deletions src/validation/__tests__/KnownOperationTypesRules-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { describe, it } from 'mocha';

import { KnownOperationTypesRule } from '../rules/KnownOperationTypesRule.js';

import { expectValidationErrors } from './harness.js';

function expectErrors(queryStr: string) {
return expectValidationErrors(KnownOperationTypesRule, queryStr);
}

function expectValid(queryStr: string) {
expectErrors(queryStr).toDeepEqual([]);
}

describe('Validate: Known operation types', () => {
it('one known operation', () => {
expectValid(`
{ field }
`);
});

it('unknown mutation operation', () => {
expectErrors(`
mutation { field }
`).toDeepEqual([
{
message: 'The mutation operation is not supported by the schema.',
locations: [{ line: 2, column: 7 }],
},
]);
});

yaacovCR marked this conversation as resolved.
Show resolved Hide resolved
it('unknown subscription operation', () => {
expectErrors(`
subscription { field }
`).toDeepEqual([
{
message: 'The subscription operation is not supported by the schema.',
locations: [{ line: 2, column: 7 }],
},
]);
});

it('mixture of known and unknown operations', () => {
expectErrors(`
query { field }
mutation { field }
subscription { field }
`).toDeepEqual([
{
message: 'The mutation operation is not supported by the schema.',
locations: [{ line: 3, column: 7 }],
},
{
message: 'The subscription operation is not supported by the schema.',
locations: [{ line: 4, column: 7 }],
},
]);
});
});
3 changes: 3 additions & 0 deletions src/validation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export { KnownDirectivesRule } from './rules/KnownDirectivesRule.js';
// Spec Section: "Fragment spread target defined"
export { KnownFragmentNamesRule } from './rules/KnownFragmentNamesRule.js';

// Spec Section: "Operation Type Existence"
export { KnownOperationTypesRule } from './rules/KnownOperationTypesRule.js';

yaacovCR marked this conversation as resolved.
Show resolved Hide resolved
// Spec Section: "Fragment Spread Type Existence"
export { KnownTypeNamesRule } from './rules/KnownTypeNamesRule.js';

Expand Down
32 changes: 32 additions & 0 deletions src/validation/rules/KnownOperationTypesRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { GraphQLError } from '../../error/GraphQLError.js';

import type { ASTVisitor } from '../../language/visitor.js';

import type { ValidationContext } from '../ValidationContext.js';

/**
* Known Operation Types
*
* A GraphQL document is only valid if when it contains an operation,
* the root type for the operation exists within the schema.
*
* See https://spec.graphql.org/draft/#sec-Operation-Type-Existence
*/
export function KnownOperationTypesRule(
context: ValidationContext,
): ASTVisitor {
const schema = context.getSchema();
return {
OperationDefinition(node) {
const operation = node.operation;
if (!schema.getRootType(operation)) {
context.reportError(
new GraphQLError(
`The ${operation} operation is not supported by the schema.`,
{ nodes: node },
),
);
}
},
};
}
3 changes: 3 additions & 0 deletions src/validation/specifiedRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
import { KnownDirectivesRule } from './rules/KnownDirectivesRule.js';
// Spec Section: "Fragment spread target defined"
import { KnownFragmentNamesRule } from './rules/KnownFragmentNamesRule.js';
// Spec Section: "Operation Type Existence"
import { KnownOperationTypesRule } from './rules/KnownOperationTypesRule.js';
// Spec Section: "Fragment Spread Type Existence"
import { KnownTypeNamesRule } from './rules/KnownTypeNamesRule.js';
// Spec Section: "Lone Anonymous Operation"
Expand Down Expand Up @@ -91,6 +93,7 @@ export const recommendedRules = Object.freeze([MaxIntrospectionDepthRule]);
*/
export const specifiedRules: ReadonlyArray<ValidationRule> = Object.freeze([
ExecutableDefinitionsRule,
KnownOperationTypesRule,
UniqueOperationNamesRule,
LoneAnonymousOperationRule,
SingleFieldSubscriptionsRule,
Expand Down
Loading