class JSONAPI::RequestParser

Attributes

context[RW]
controller_module_path[RW]
errors[RW]
fields[RW]
filters[RW]
include[RW]
include_directives[RW]
paginator[RW]
params[RW]
server_error_callbacks[RW]
sort_criteria[RW]
source_id[RW]
source_klass[RW]
warnings[RW]

Public Class Methods

new(params = nil, options = {}) click to toggle source
# File lib/jsonapi/request_parser.rb, line 7
def initialize(params = nil, options = {})
  @params = params
  if params
    controller_path = params.fetch(:controller, '')
    @controller_module_path = controller_path.include?('/') ? controller_path.rpartition('/').first + '/' : ''
  else
    @controller_module_path = ''
  end

  @context = options[:context]
  @key_formatter = options.fetch(:key_formatter, JSONAPI.configuration.key_formatter)
  @errors = []
  @warnings = []
  @server_error_callbacks = options.fetch(:server_error_callbacks, [])
end

Public Instance Methods

check_include(resource_klass, include_parts) click to toggle source
# File lib/jsonapi/request_parser.rb, line 336
def check_include(resource_klass, include_parts)
  relationship_name = unformat_key(include_parts.first)

  relationship = resource_klass._relationship(relationship_name)
  if relationship && format_key(relationship_name) == include_parts.first
    unless relationship.allow_include?(context)
      fail JSONAPI::Exceptions::InvalidInclude.new(format_key(resource_klass._type), include_parts.first)
    end

    unless include_parts.last.empty?
      check_include(Resource.resource_klass_for(resource_klass.module_path + relationship.class_name.to_s.underscore),
                    include_parts.last.partition('.'))
    end
  else
    fail JSONAPI::Exceptions::InvalidInclude.new(format_key(resource_klass._type), include_parts.first)
  end
  true
end
check_sort_criteria(resource_klass, sort_criteria) click to toggle source
# File lib/jsonapi/request_parser.rb, line 442
def check_sort_criteria(resource_klass, sort_criteria)
  sort_field = sort_criteria[:field]

  unless resource_klass.sortable_field?(sort_field.to_sym, context)
    fail JSONAPI::Exceptions::InvalidSortCriteria.new(format_key(resource_klass._type), sort_field)
  end
end
each(_response_document) { |operation| ... } click to toggle source
# File lib/jsonapi/request_parser.rb, line 27
def each(_response_document)
  operation = setup_base_op(params)
  if @errors.any?
    fail JSONAPI::Exceptions::Errors.new(@errors)
  else
    yield operation
  end
rescue ActionController::ParameterMissing => e
  fail JSONAPI::Exceptions::ParameterMissing.new(e.param, error_object_overrides)
end
error_object_overrides() click to toggle source
# File lib/jsonapi/request_parser.rb, line 23
def error_object_overrides
  {}
end
format_key(key) click to toggle source
# File lib/jsonapi/request_parser.rb, line 732
def format_key(key)
  @key_formatter.format(key)
end
parse_add_relationship_operation(resource_klass, verified_params, relationship, parent_key) click to toggle source
# File lib/jsonapi/request_parser.rb, line 667
def parse_add_relationship_operation(resource_klass, verified_params, relationship, parent_key)
  if relationship.is_a?(JSONAPI::Relationship::ToMany)
    return JSONAPI::Operation.new(
        :create_to_many_relationships,
        resource_klass,
        context: @context,
        resource_id: parent_key,
        relationship_type: relationship.name,
        data: verified_params[:to_many].values[0]
    )
  end
end
parse_fields(resource_klass, fields) click to toggle source
# File lib/jsonapi/request_parser.rb, line 282
def parse_fields(resource_klass, fields)
  extracted_fields = {}

  return extracted_fields if fields.nil?

  # Extract the fields for each type from the fields parameters
  if fields.is_a?(ActionController::Parameters)
    fields.each do |field, value|
      if value.is_a?(Array)
        resource_fields = value
      else
        resource_fields = value.split(',') unless value.nil? || value.empty?
      end
      extracted_fields[field] = resource_fields
    end
  else
    fail JSONAPI::Exceptions::InvalidFieldFormat.new(error_object_overrides)
  end

  # Validate the fields
  validated_fields = {}
  extracted_fields.each do |type, values|
    underscored_type = unformat_key(type)
    validated_fields[type] = []
    begin
      if type != format_key(type)
        fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
      end
      type_resource = Resource.resource_klass_for(resource_klass.module_path + underscored_type.to_s)
    rescue NameError
      fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
    end

    if type_resource.nil?
      fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
    else
      unless values.nil?
        valid_fields = type_resource.fields.collect { |key| format_key(key) }
        values.each do |field|
          if valid_fields.include?(field)
            validated_fields[type].push unformat_key(field)
          else
            fail JSONAPI::Exceptions::InvalidField.new(type, field, error_object_overrides)
          end
        end
      else
        fail JSONAPI::Exceptions::InvalidField.new(type, 'nil', error_object_overrides)
      end
    end
  end

  validated_fields.deep_transform_keys { |key| unformat_key(key) }
end
parse_filters(resource_klass, filters) click to toggle source
# File lib/jsonapi/request_parser.rb, line 378
def parse_filters(resource_klass, filters)
  parsed_filters = {}

  # apply default filters
  resource_klass._allowed_filters.each do |filter, opts|
    next if opts[:default].nil? || !parsed_filters[filter].nil?
    parsed_filters[filter] = opts[:default]
  end

  return parsed_filters unless filters

  unless filters.class.method_defined?(:each)
    @errors.concat(JSONAPI::Exceptions::InvalidFiltersSyntax.new(filters).errors)
    return {}
  end

  unless JSONAPI.configuration.allow_filter
    fail JSONAPI::Exceptions::ParameterNotAllowed.new(:filter)
  end

  filters.each do |key, value|
    filter = unformat_key(key)
    if resource_klass._allowed_filter?(filter)
      parsed_filters[filter] = value
    else
      fail JSONAPI::Exceptions::FilterNotAllowed.new(key)
    end
  end

  parsed_filters
end
parse_include_directives(resource_klass, raw_include) click to toggle source
# File lib/jsonapi/request_parser.rb, line 355
def parse_include_directives(resource_klass, raw_include)
  raw_include ||= ''

  included_resources = []
  begin
    included_resources += raw_include.is_a?(Array) ? raw_include : CSV.parse_line(raw_include) || []
  rescue CSV::MalformedCSVError
    fail JSONAPI::Exceptions::InvalidInclude.new(format_key(resource_klass._type), raw_include)
  end

  begin
    result = included_resources.compact.map do |included_resource|
      check_include(resource_klass, included_resource.partition('.'))
      unformat_key(included_resource).to_s
    end

    return JSONAPI::IncludeDirectives.new(resource_klass, result)
  rescue JSONAPI::Exceptions::InvalidInclude => e
    @errors.concat(e.errors)
    return {}
  end
end
parse_modify_relationship_action(modification_type, params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 254
def parse_modify_relationship_action(modification_type, params, resource_klass)
  relationship_type = params.require(:relationship)

  parent_key = params.require(resource_klass._as_parent_key)
  relationship = resource_klass._relationship(relationship_type)

  # Removals of to-one relationships are done implicitly and require no specification of data
  data_required = !(modification_type == :remove && relationship.is_a?(JSONAPI::Relationship::ToOne))

  if data_required
    data = params.fetch(:data)
    object_params = { relationships: { format_key(relationship.name) => { data: data } } }

    verified_params = parse_params(resource_klass, object_params, resource_klass.updatable_fields(@context))

    parse_arguments = [resource_klass, verified_params, relationship, parent_key]
  else
    parse_arguments = [resource_klass, params, relationship, parent_key]
  end

  send(:"parse_#{modification_type}_relationship_operation", *parse_arguments)
end
parse_pagination(resource_klass, page) click to toggle source
# File lib/jsonapi/request_parser.rb, line 277
def parse_pagination(resource_klass, page)
  paginator_name = resource_klass._paginator
  JSONAPI::Paginator.paginator_for(paginator_name).new(page) unless paginator_name == :none
end
parse_params(resource_klass, params, allowed_fields) click to toggle source
# File lib/jsonapi/request_parser.rb, line 493
def parse_params(resource_klass, params, allowed_fields)
  verify_permitted_params(params, allowed_fields)

  checked_attributes = {}
  checked_to_one_relationships = {}
  checked_to_many_relationships = {}

  params.each do |key, value|
    case key.to_s
      when 'relationships'
        value.each do |link_key, link_value|
          param = unformat_key(link_key)
          relationship = resource_klass._relationship(param)

          if relationship.is_a?(JSONAPI::Relationship::ToOne)
            checked_to_one_relationships[param] = parse_to_one_relationship(resource_klass, link_value, relationship)
          elsif relationship.is_a?(JSONAPI::Relationship::ToMany)
            parse_to_many_relationship(resource_klass, link_value, relationship) do |result_val|
              checked_to_many_relationships[param] = result_val
            end
          end
        end
      when 'id'
        checked_attributes['id'] = unformat_value(resource_klass, :id, value)
      when 'attributes'
        value.each do |key, value|
          param = unformat_key(key)
          checked_attributes[param] = unformat_value(resource_klass, param, value)
        end
    end
  end

  return {
      'attributes' => checked_attributes,
      'to_one' => checked_to_one_relationships,
      'to_many' => checked_to_many_relationships
  }.deep_transform_keys { |key| unformat_key(key) }
end
parse_remove_relationship_operation(resource_klass, params, relationship, parent_key) click to toggle source
# File lib/jsonapi/request_parser.rb, line 708
def parse_remove_relationship_operation(resource_klass, params, relationship, parent_key)
  operation_base_args = [resource_klass].push(
      context: @context,
      resource_id: parent_key,
      relationship_type: relationship.name
  )

  if relationship.is_a?(JSONAPI::Relationship::ToMany)
    operation_args = operation_base_args.dup
    keys = params[:to_many].values[0]
    operation_args[1] = operation_args[1].merge(associated_keys: keys)
    JSONAPI::Operation.new(:remove_to_many_relationships, *operation_args)
  else
    JSONAPI::Operation.new(:remove_to_one_relationship, *operation_base_args)
  end
end
parse_sort_criteria(resource_klass, sort_criteria) click to toggle source
# File lib/jsonapi/request_parser.rb, line 410
def parse_sort_criteria(resource_klass, sort_criteria)
  return unless sort_criteria.present?

  unless JSONAPI.configuration.allow_sort
    fail JSONAPI::Exceptions::ParameterNotAllowed.new(:sort)
  end

  if sort_criteria.is_a?(Array)
    sorts = sort_criteria
  elsif sort_criteria.is_a?(String)
    begin
      raw = URI.decode_www_form_component(sort_criteria)
      sorts = CSV.parse_line(raw)
    rescue CSV::MalformedCSVError
      fail JSONAPI::Exceptions::InvalidSortCriteria.new(format_key(resource_klass._type), raw)
    end
  end

  @sort_criteria = sorts.collect do |sort|
    if sort.start_with?('-')
      criteria = { field: unformat_key(sort[1..-1]).to_s }
      criteria[:direction] = :desc
    else
      criteria = { field: unformat_key(sort).to_s }
      criteria[:direction] = :asc
    end

    check_sort_criteria(resource_klass, criteria)
    criteria
  end
end
parse_to_many_relationship(resource_klass, link_value, relationship, &add_result) click to toggle source
# File lib/jsonapi/request_parser.rb, line 558
def parse_to_many_relationship(resource_klass, link_value, relationship, &add_result)
  if (link_value.is_a?(Hash) || link_value.is_a?(ActionController::Parameters))
    linkage = link_value[:data]
  else
    fail JSONAPI::Exceptions::InvalidLinksObject.new(error_object_overrides)
  end

  links_object = parse_to_many_links_object(linkage)

  if links_object.length == 0
    add_result.call([])
  else
    if relationship.polymorphic?
      polymorphic_results = []

      links_object.each_pair do |type, keys|
        type_name = unformat_key(type).to_s

        relationship_resource_klass = resource_klass.resource_klass_for(relationship.class_name)
        relationship_klass = relationship_resource_klass._model_class

        linkage_object_resource_klass = resource_klass.resource_klass_for(type_name)
        linkage_object_klass = linkage_object_resource_klass._model_class

        unless linkage_object_klass == relationship_klass || linkage_object_klass.in?(relationship_klass.subclasses)
          fail JSONAPI::Exceptions::TypeMismatch.new(type_name)
        end

        relationship_ids = relationship_resource_klass.verify_keys(keys, @context)
         polymorphic_results << { type: type, ids: relationship_ids }
      end

      add_result.call polymorphic_results
    else
      relationship_type = unformat_key(relationship.type).to_s

      if links_object.length > 1 || !links_object.has_key?(relationship_type)
        fail JSONAPI::Exceptions::TypeMismatch.new(links_object[:type])
      end

      relationship_resource_klass = Resource.resource_klass_for(resource_klass.module_path + relationship_type)
      add_result.call relationship_resource_klass.verify_keys(links_object[relationship_type], @context)
    end
  end
end
parse_to_one_relationship(resource_klass, link_value, relationship) click to toggle source
# File lib/jsonapi/request_parser.rb, line 532
def parse_to_one_relationship(resource_klass, link_value, relationship)
  if link_value.nil?
    linkage = nil
  else
    linkage = link_value[:data]
  end

  links_object = parse_to_one_links_object(linkage)
  if !relationship.polymorphic? && links_object[:type] && (links_object[:type].to_s != relationship.type.to_s)
    fail JSONAPI::Exceptions::TypeMismatch.new(links_object[:type], error_object_overrides)
  end

  unless links_object[:id].nil?
    resource = resource_klass || Resource
    relationship_resource = resource.resource_klass_for(unformat_key(relationship.options[:class_name] || links_object[:type]).to_s)
    relationship_id = relationship_resource.verify_key(links_object[:id], @context)
    if relationship.polymorphic?
      { id: relationship_id, type: unformat_key(links_object[:type].to_s) }
    else
      relationship_id
    end
  else
    nil
  end
end
parse_update_relationship_operation(resource_klass, verified_params, relationship, parent_key) click to toggle source
# File lib/jsonapi/request_parser.rb, line 680
def parse_update_relationship_operation(resource_klass, verified_params, relationship, parent_key)
  options = {
      context: @context,
      resource_id: parent_key,
      relationship_type: relationship.name
  }

  if relationship.is_a?(JSONAPI::Relationship::ToOne)
    if relationship.polymorphic?
      options[:key_value] = verified_params[:to_one].values[0][:id]
      options[:key_type] = verified_params[:to_one].values[0][:type]

      operation_type = :replace_polymorphic_to_one_relationship
    else
      options[:key_value] = verified_params[:to_one].values[0]
      operation_type = :replace_to_one_relationship
    end
  elsif relationship.is_a?(JSONAPI::Relationship::ToMany)
    unless relationship.acts_as_set
      fail JSONAPI::Exceptions::ToManySetReplacementForbidden.new
    end
    options[:data] = verified_params[:to_many].values[0]
    operation_type = :replace_to_many_relationships
  end

  JSONAPI::Operation.new(operation_type, resource_klass, options)
end
resolve_singleton_id(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 725
def resolve_singleton_id(params, resource_klass)
  if resource_klass.singleton? && params[:id].nil?
    key = resource_klass.singleton_key(context)
    params[:id] = key
  end
end
setup_base_op(params) click to toggle source
# File lib/jsonapi/request_parser.rb, line 47
def setup_base_op(params)
  return if params.nil?

  resource_klass = Resource.resource_klass_for(params[:controller]) if params[:controller]

  setup_action_method_name = "setup_#{params[:action]}_action"
  if respond_to?(setup_action_method_name)
    raise params[:_parser_exception] if params[:_parser_exception]
    send(setup_action_method_name, params, resource_klass)
  end
rescue ActionController::ParameterMissing => e
  @errors.concat(JSONAPI::Exceptions::ParameterMissing.new(e.param, error_object_overrides).errors)
rescue JSONAPI::Exceptions::Error => e
  e.error_object_overrides.merge! error_object_overrides
  @errors.concat(e.errors)
end
setup_create_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 172
def setup_create_action(params, resource_klass)
  fields = parse_fields(resource_klass, params[:fields])
  include_directives = parse_include_directives(resource_klass, params[:include])

  data = params.require(:data)

  unless data.respond_to?(:each_pair)
    fail JSONAPI::Exceptions::InvalidDataFormat.new(error_object_overrides)
  end

  verify_type(data[:type], resource_klass)

  data = parse_params(resource_klass, data, resource_klass.creatable_fields(@context))

  JSONAPI::Operation.new(
      :create_resource,
      resource_klass,
      context: @context,
      data: data,
      fields: fields,
      include_directives: include_directives,
      warnings: @warnings
  )
end
setup_create_relationship_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 197
def setup_create_relationship_action(params, resource_klass)
  resolve_singleton_id(params, resource_klass)
  parse_modify_relationship_action(:add, params, resource_klass)
end
setup_destroy_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 240
def setup_destroy_action(params, resource_klass)
  resolve_singleton_id(params, resource_klass)
  JSONAPI::Operation.new(
      :remove_resource,
      resource_klass,
      context: @context,
      resource_id: resource_klass.verify_key(params.require(:id), @context))
end
setup_destroy_relationship_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 249
def setup_destroy_relationship_action(params, resource_klass)
  resolve_singleton_id(params, resource_klass)
  parse_modify_relationship_action(:remove, params, resource_klass)
end
setup_index_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 64
def setup_index_action(params, resource_klass)
  fields = parse_fields(resource_klass, params[:fields])
  include_directives = parse_include_directives(resource_klass, params[:include])
  filters = parse_filters(resource_klass, params[:filter])
  sort_criteria = parse_sort_criteria(resource_klass, params[:sort])
  paginator = parse_pagination(resource_klass, params[:page])

  JSONAPI::Operation.new(
      :find,
      resource_klass,
      context: context,
      filters: filters,
      include_directives: include_directives,
      sort_criteria: sort_criteria,
      paginator: paginator,
      fields: fields
  )
end
setup_show_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 132
def setup_show_action(params, resource_klass)
  resolve_singleton_id(params, resource_klass)
  fields = parse_fields(resource_klass, params[:fields])
  include_directives = parse_include_directives(resource_klass, params[:include])
  id = params[:id]

  JSONAPI::Operation.new(
      :show,
      resource_klass,
      context: @context,
      id: id,
      include_directives: include_directives,
      fields: fields,
      allowed_resources: params[:allowed_resources]
  )
end
setup_show_relationship_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 149
def setup_show_relationship_action(params, resource_klass)
  resolve_singleton_id(params, resource_klass)
  relationship_type = params[:relationship]
  parent_key = params.require(resource_klass._as_parent_key)
  include_directives = parse_include_directives(resource_klass, params[:include])
  filters = parse_filters(resource_klass, params[:filter])
  sort_criteria = parse_sort_criteria(resource_klass, params[:sort])
  paginator = parse_pagination(resource_klass, params[:page])

  JSONAPI::Operation.new(
      :show_relationship,
      resource_klass,
      context: @context,
      relationship_type: relationship_type,
      parent_key: resource_klass.verify_key(parent_key),
      filters: filters,
      sort_criteria: sort_criteria,
      paginator: paginator,
      fields: fields,
      include_directives: include_directives
  )
end
setup_update_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 206
def setup_update_action(params, resource_klass)
  resolve_singleton_id(params, resource_klass)
  fields = parse_fields(resource_klass, params[:fields])
  include_directives = parse_include_directives(resource_klass, params[:include])

  data = params.require(:data)
  key = params[:id]

  fail JSONAPI::Exceptions::InvalidDataFormat.new(error_object_overrides) unless data.respond_to?(:each_pair)

  fail JSONAPI::Exceptions::MissingKey.new(error_object_overrides) if data[:id].nil?

  resource_id = data.require(:id)
  # Singleton resources may not have the ID set in the URL
  if key
    fail JSONAPI::Exceptions::KeyNotIncludedInURL.new(resource_id) if key.to_s != resource_id.to_s
  end

  data.delete(:id)

  verify_type(data[:type], resource_klass)

  JSONAPI::Operation.new(
      :replace_fields,
      resource_klass,
      context: @context,
      resource_id: resource_id,
      data: parse_params(resource_klass, data, resource_klass.updatable_fields(@context)),
      fields: fields,
      include_directives: include_directives,
      warnings: @warnings
  )
end
setup_update_relationship_action(params, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 202
def setup_update_relationship_action(params, resource_klass)
  parse_modify_relationship_action(:update, params, resource_klass)
end
transactional?() click to toggle source
# File lib/jsonapi/request_parser.rb, line 38
def transactional?
  case params[:action]
    when 'index', 'show_related_resource', 'index_related_resources', 'show', 'show_relationship'
      return false
    else
      return true
  end
end
unformat_key(key) click to toggle source
# File lib/jsonapi/request_parser.rb, line 736
def unformat_key(key)
  unformatted_key = @key_formatter.unformat(key)
  unformatted_key.nil? ? nil : unformatted_key.to_sym
end
unformat_value(resource_klass, attribute, value) click to toggle source
# File lib/jsonapi/request_parser.rb, line 604
def unformat_value(resource_klass, attribute, value)
  value_formatter = JSONAPI::ValueFormatter.value_formatter_for(resource_klass._attribute_options(attribute)[:format])
  value_formatter.unformat(value)
end
verify_permitted_params(params, allowed_fields) click to toggle source
# File lib/jsonapi/request_parser.rb, line 609
def verify_permitted_params(params, allowed_fields)
  formatted_allowed_fields = allowed_fields.collect { |field| format_key(field).to_sym }
  params_not_allowed = []

  params.each do |key, value|
    case key.to_s
      when 'relationships'
        value.keys.each do |links_key|
          unless formatted_allowed_fields.include?(links_key.to_sym)
            if JSONAPI.configuration.raise_if_parameters_not_allowed
              fail JSONAPI::Exceptions::ParameterNotAllowed.new(links_key, error_object_overrides)
            else
              params_not_allowed.push(links_key)
              value.delete links_key
            end
          end
        end
      when 'attributes'
        value.each do |attr_key, _attr_value|
          unless formatted_allowed_fields.include?(attr_key.to_sym)
            if JSONAPI.configuration.raise_if_parameters_not_allowed
              fail JSONAPI::Exceptions::ParameterNotAllowed.new(attr_key, error_object_overrides)
            else
              params_not_allowed.push(attr_key)
              value.delete attr_key
            end
          end
        end
      when 'type'
      when 'id'
        unless formatted_allowed_fields.include?(:id)
          if JSONAPI.configuration.raise_if_parameters_not_allowed
            fail JSONAPI::Exceptions::ParameterNotAllowed.new(:id, error_object_overrides)
          else
            params_not_allowed.push(:id)
            params.delete :id
          end
        end
      else
        if JSONAPI.configuration.raise_if_parameters_not_allowed
          fail JSONAPI::Exceptions::ParameterNotAllowed.new(key, error_object_overrides)
        else
          params_not_allowed.push(key)
          params.delete key
        end
    end
  end

  if params_not_allowed.length > 0
    params_not_allowed_warnings = params_not_allowed.map do |param|
      JSONAPI::Warning.new(code: JSONAPI::PARAM_NOT_ALLOWED,
                           title: 'Param not allowed',
                           detail: "#{param} is not allowed.")
    end
    self.warnings.concat(params_not_allowed_warnings)
  end
end
verify_type(type, resource_klass) click to toggle source
# File lib/jsonapi/request_parser.rb, line 450
def verify_type(type, resource_klass)
  if type.nil?
    fail JSONAPI::Exceptions::ParameterMissing.new(:type)
  elsif unformat_key(type).to_sym != resource_klass._type
    fail JSONAPI::Exceptions::InvalidResource.new(type, error_object_overrides)
  end
end