You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.8 KiB
86 lines
2.8 KiB
'use strict'; |
|
|
|
Object.defineProperty(exports, '__esModule', { |
|
value: true, |
|
}); |
|
exports.SingleFieldSubscriptionsRule = SingleFieldSubscriptionsRule; |
|
|
|
var _GraphQLError = require('../../error/GraphQLError.js'); |
|
|
|
var _kinds = require('../../language/kinds.js'); |
|
|
|
var _collectFields = require('../../execution/collectFields.js'); |
|
|
|
/** |
|
* Subscriptions must only include a non-introspection field. |
|
* |
|
* A GraphQL subscription is valid only if it contains a single root field and |
|
* that root field is not an introspection field. |
|
* |
|
* See https://spec.graphql.org/draft/#sec-Single-root-field |
|
*/ |
|
function SingleFieldSubscriptionsRule(context) { |
|
return { |
|
OperationDefinition(node) { |
|
if (node.operation === 'subscription') { |
|
const schema = context.getSchema(); |
|
const subscriptionType = schema.getSubscriptionType(); |
|
|
|
if (subscriptionType) { |
|
const operationName = node.name ? node.name.value : null; |
|
const variableValues = Object.create(null); |
|
const document = context.getDocument(); |
|
const fragments = Object.create(null); |
|
|
|
for (const definition of document.definitions) { |
|
if (definition.kind === _kinds.Kind.FRAGMENT_DEFINITION) { |
|
fragments[definition.name.value] = definition; |
|
} |
|
} |
|
|
|
const fields = (0, _collectFields.collectFields)( |
|
schema, |
|
fragments, |
|
variableValues, |
|
subscriptionType, |
|
node.selectionSet, |
|
); |
|
|
|
if (fields.size > 1) { |
|
const fieldSelectionLists = [...fields.values()]; |
|
const extraFieldSelectionLists = fieldSelectionLists.slice(1); |
|
const extraFieldSelections = extraFieldSelectionLists.flat(); |
|
context.reportError( |
|
new _GraphQLError.GraphQLError( |
|
operationName != null |
|
? `Subscription "${operationName}" must select only one top level field.` |
|
: 'Anonymous Subscription must select only one top level field.', |
|
{ |
|
nodes: extraFieldSelections, |
|
}, |
|
), |
|
); |
|
} |
|
|
|
for (const fieldNodes of fields.values()) { |
|
const field = fieldNodes[0]; |
|
const fieldName = field.name.value; |
|
|
|
if (fieldName.startsWith('__')) { |
|
context.reportError( |
|
new _GraphQLError.GraphQLError( |
|
operationName != null |
|
? `Subscription "${operationName}" must not select an introspection top level field.` |
|
: 'Anonymous Subscription must not select an introspection top level field.', |
|
{ |
|
nodes: fieldNodes, |
|
}, |
|
), |
|
); |
|
} |
|
} |
|
} |
|
} |
|
}, |
|
}; |
|
}
|
|
|