Class: GraphQL::Language::SanitizedPrinter
- Defined in:
- lib/graphql/language/sanitized_printer.rb
Overview
A custom printer used to print sanitized queries. It inlines provided variables within the query for facilitate logging and analysis of queries.
The printer returns nil
if the query is invalid.
Since the GraphQL Ruby AST for a GraphQL query doesnt contain any reference on the type of fields or arguments, we have to track the current object, field and input type while printing the query.
Constant Summary collapse
- REDACTED =
"\"<REDACTED>\""
Instance Method Summary collapse
-
#coerce_argument_value_to_list?(type, value) ⇒ Boolean
-
#initialize(query, inline_variables: true) ⇒ SanitizedPrinter
constructor
A new instance of SanitizedPrinter.
-
#print_argument(argument) ⇒ Object
-
#print_directive(directive) ⇒ Object
-
#print_field(field, indent: "") ⇒ Object
-
#print_fragment_definition(fragment_def, indent: "") ⇒ Object
-
#print_inline_fragment(inline_fragment, indent: "") ⇒ Object
-
#print_node(node, indent: "") ⇒ Object
-
#print_operation_definition(operation_definition, indent: "") ⇒ Object
Print the operation definition but do not include the variable definitions since we will inline them within the query.
-
#print_variable_identifier(variable_id) ⇒ Object
-
#redact_argument_value?(argument, value) ⇒ Boolean
Indicates whether or not to redact non-null values for the given argument.
-
#redacted_argument_value(argument) ⇒ Object
Returns the value to use for redacted versions of the given argument.
-
#sanitized_query_string ⇒ String?
A scrubbed query string, if the query was valid.
Methods inherited from Printer
Constructor Details
#initialize(query, inline_variables: true) ⇒ SanitizedPrinter
Returns a new instance of SanitizedPrinter.
22 23 24 25 26 27 28 |
# File 'lib/graphql/language/sanitized_printer.rb', line 22 def initialize(query, inline_variables: true) @query = query @current_type = nil @current_field = nil @current_input_type = nil @inline_variables = inline_variables end |
Instance Method Details
#coerce_argument_value_to_list?(type, value) ⇒ Boolean
99 100 101 102 103 104 |
# File 'lib/graphql/language/sanitized_printer.rb', line 99 def coerce_argument_value_to_list?(type, value) type.list? && !value.is_a?(Array) && !value.nil? && !value.is_a?(GraphQL::Language::Nodes::VariableIdentifier) end |
#print_argument(argument) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/graphql/language/sanitized_printer.rb', line 76 def print_argument(argument) # We won't have type information if we're recursing into a custom scalar return super if @current_input_type && @current_input_type.kind.scalar? arg_owner = @current_input_type || @current_directive || @current_field old_current_argument = @current_argument @current_argument = arg_owner.arguments[argument.name] old_input_type = @current_input_type @current_input_type = @current_argument.type.non_null? ? @current_argument.type.of_type : @current_argument.type argument_value = if coerce_argument_value_to_list?(@current_input_type, argument.value) [argument.value] else argument.value end res = "#{argument.name}: #{print_node(argument_value)}".dup @current_input_type = old_input_type @current_argument = old_current_argument res end |
#print_directive(directive) ⇒ Object
149 150 151 152 153 154 155 156 |
# File 'lib/graphql/language/sanitized_printer.rb', line 149 def print_directive(directive) @current_directive = query.schema.directives[directive.name] res = super @current_directive = nil res end |
#print_field(field, indent: "") ⇒ Object
115 116 117 118 119 120 121 122 |
# File 'lib/graphql/language/sanitized_printer.rb', line 115 def print_field(field, indent: "") @current_field = query.schema.get_field(@current_type, field.name) old_type = @current_type @current_type = @current_field.type.unwrap res = super @current_type = old_type res end |
#print_fragment_definition(fragment_def, indent: "") ⇒ Object
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/graphql/language/sanitized_printer.rb', line 138 def print_fragment_definition(fragment_def, indent: "") old_type = @current_type @current_type = query.schema.types[fragment_def.type.name] res = super @current_type = old_type res end |
#print_inline_fragment(inline_fragment, indent: "") ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/graphql/language/sanitized_printer.rb', line 124 def print_inline_fragment(inline_fragment, indent: "") old_type = @current_type if inline_fragment.type @current_type = query.schema.types[inline_fragment.type.name] end res = super @current_type = old_type res end |
#print_node(node, indent: "") ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/graphql/language/sanitized_printer.rb', line 39 def print_node(node, indent: "") case node when FalseClass, Float, Integer, String, TrueClass if @current_argument && redact_argument_value?(@current_argument, node) redacted_argument_value(@current_argument) else super end when Array old_input_type = @current_input_type if @current_input_type && @current_input_type.list? @current_input_type = @current_input_type.of_type @current_input_type = @current_input_type.of_type if @current_input_type.non_null? end res = super @current_input_type = old_input_type res else super end end |
#print_operation_definition(operation_definition, indent: "") ⇒ Object
Print the operation definition but do not include the variable definitions since we will inline them within the query
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/graphql/language/sanitized_printer.rb', line 160 def print_operation_definition(operation_definition, indent: "") old_type = @current_type @current_type = query.schema.public_send(operation_definition.operation_type) if @inline_variables out = "#{indent}#{operation_definition.operation_type}".dup out << " #{operation_definition.name}" if operation_definition.name out << print_directives(operation_definition.directives) out << print_selections(operation_definition.selections, indent: indent) else out = super end @current_type = old_type out end |
#print_variable_identifier(variable_id) ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'lib/graphql/language/sanitized_printer.rb', line 106 def print_variable_identifier(variable_id) if @inline_variables variable_value = query.variables[variable_id.name] print_node(value_to_ast(variable_value, @current_input_type)) else super end end |
#redact_argument_value?(argument, value) ⇒ Boolean
Indicates whether or not to redact non-null values for the given argument. Defaults to redacting all strings arguments but this can be customized by subclasses.
64 65 66 67 68 |
# File 'lib/graphql/language/sanitized_printer.rb', line 64 def redact_argument_value?(argument, value) # Default to redacting any strings or custom scalars encoded as strings type = argument.type.unwrap value.is_a?(String) && type.kind.scalar? && (type.graphql_name == "String" || !type.default_scalar?) end |
#redacted_argument_value(argument) ⇒ Object
Returns the value to use for redacted versions of the given argument. Defaults to the
string “
72 73 74 |
# File 'lib/graphql/language/sanitized_printer.rb', line 72 def redacted_argument_value(argument) REDACTED end |
#sanitized_query_string ⇒ String?
Returns A scrubbed query string, if the query was valid.
31 32 33 34 35 36 37 |
# File 'lib/graphql/language/sanitized_printer.rb', line 31 def sanitized_query_string if query.valid? print(query.document) else nil end end |