class JSONAPI::Sideposting::LidResolver
def [](lid)
def [](lid) @map[lid.to_s] end
def add(lid, type:, id:)
def add(lid, type:, id:) raise ArgumentError, "lid is required" if lid.blank? raise ArgumentError, "type is required" if type.blank? raise ArgumentError, "id is required" if id.blank? @map[lid.to_s] = { type: type.to_s, id: id.to_s } self end
def initialize
def initialize @map = {} end
def resolve(data)
def resolve(data) return data if data.nil? case data when Hash resolve_hash(data) when Array data.map { |item| resolve(item) } else data end end
def resolve_hash(hash)
def resolve_hash(hash) result = {} hash.each do |key, value| result[key] = if resource_identifier_with_lid?(value) resolve_identifier(value) else resolve(value) end end result end
def resolve_identifier(identifier)
def resolve_identifier(identifier) identifier = identifier.symbolize_keys if identifier.respond_to?(:symbolize_keys) lid = (identifier[:lid] || identifier["lid"]).to_s resolved = @map[lid] unless resolved raise ArgumentError, "Unknown lid '#{lid}' (ensure the resource is in the top-level included array)" end { type: resolved[:type], id: resolved[:id] } end
def resource_identifier_with_lid?(value)
def resource_identifier_with_lid?(value) return false unless value.is_a?(Hash) value = value.symbolize_keys if value.respond_to?(:symbolize_keys) type = value[:type] || value["type"] lid = value[:lid] || value["lid"] type.present? && lid.to_s.present? end