1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! Partial execition of the
//! [schema introspection](https://spec.graphql.org/draft/#sec-Schema-Introspection)
//! portion of a query
//!
//! The main entry point is [`partial_execute`].
use crateHashMap;
use crateOperation;
use crateOperationMap;
use cratecoerce_variable_values;
use crateRequestError;
use crateExecution;
use crateFieldError;
use crateObjectValue;
use crateResolveInfo;
use crateResolvedValue;
use crateExecutionResponse;
use crateJsonMap;
use crateImplementers;
use crateValid;
use crateExecutableDocument;
use crateName;
use crateSchema;
pub
/// Check that the nesting level of some list fields does not exceed a fixed depth limit.
///
/// Since [the schema-introspection schema][s] is recursive,
/// a malicious query could cause huge responses that grow exponentially to the nesting depth.
///
/// An error result is a [request error](https://spec.graphql.org/draft/#request-error):
/// execution must not run at all,
/// and the GraphQL response must not have a `data` key (which is different from `data: null`).
///
/// The exact criteria may change in future apollo-compiler versions.
///
/// [s]: https://spec.graphql.org/draft/#sec-Schema-Introspection.Schema-Introspection-Schema
/// Excecutes the [schema introspection](https://spec.graphql.org/draft/#sec-Schema-Introspection)
/// portion of a query and returns a partial response.
///
/// * Consider calling [`check_max_depth`] before this function
/// * `implementers_map` is expected to be form
/// [`schema.implementers_map()`][Schema::implementers_map],
/// allowing it to be computed once and reused for many queries
/// * `operation` is expected to be from
/// [`document.operations.get(operation_name)?`][OperationMap::get]
/// * `operation` is expected to be a query,
/// check [`operation.operation_type.is_query()`][Operation::operation_type]
/// * `variable_values` is expected to be from [`coerce_variable_values`]
///
/// Concrete [root fields][Operation::root_fields] (those with an explicit definition in the schema)
/// are **_silently ignored_**.
///
/// Only introspection meta-fields are executed:
/// `__typename` (at the response root), `__type`, and `__schema`.
/// If the operation also contains concrete fields,
/// the caller can execute them separately and merge the two partial responses.
/// To categorize which kinds of root fields are present, consider using code like:
///
/// ```
/// # use apollo_compiler::executable as exe;
/// # fn categorize_fields(document: &exe::ExecutableDocument, operation: &exe::Operation) {
/// let mut has_schema_introspection_fields = false;
/// let mut has_root_typename_fields = false;
/// let mut has_concrete_fields = false;
/// for root_field in operation.root_fields(document) {
/// match root_field.name.as_str() {
/// "__type" | "__schema" => has_schema_introspection_fields = true,
/// "__typename" => has_root_typename_fields = true,
/// _ => has_concrete_fields = true,
/// }
/// }
/// # }
/// ```