diff --git a/lib/scalingo/api/client.rb b/lib/scalingo/api/client.rb index 6b20d84..a4ccb08 100644 --- a/lib/scalingo/api/client.rb +++ b/lib/scalingo/api/client.rb @@ -1,5 +1,6 @@ require "scalingo/token_holder" require "scalingo/faraday/response" +require "scalingo/faraday/unpack_middleware" require "active_support/core_ext/hash" module Scalingo @@ -86,6 +87,7 @@ def connection(fallback_to_guest: false) def unauthenticated_connection @unauthenticated_conn ||= Faraday.new(connection_options) { |conn| + conn.response :unpack conn.response :json, content_type: /\bjson$/, parser_options: {symbolize_names: true} conn.request :json @@ -106,6 +108,7 @@ def authenticated_connection end @connection = Faraday.new(connection_options) { |conn| + conn.response :unpack conn.response :json, content_type: /\bjson$/, parser_options: {symbolize_names: true} conn.request :json conn.request :authorization, "Bearer", -> { token_holder.token&.value } @@ -119,6 +122,7 @@ def database_connection(database_id) @database_connections ||= {} @database_connections[database_id] ||= Faraday.new(connection_options) { |conn| + conn.response :unpack conn.response :json, content_type: /\bjson$/, parser_options: {symbolize_names: true} conn.request :json conn.request :authorization, "Bearer", -> { token_holder.database_tokens[database_id]&.value } diff --git a/lib/scalingo/faraday/response.rb b/lib/scalingo/faraday/response.rb index a958e60..d969f17 100644 --- a/lib/scalingo/faraday/response.rb +++ b/lib/scalingo/faraday/response.rb @@ -25,5 +25,33 @@ def server_error? def error? !success? end + + def meta + env[:response_meta] + end + + def meta? + meta.present? + end + + def pagination + return unless meta? + + meta[:pagination] + end + + def paginated? + pagination.present? + end + + def cursor_pagination + return unless meta? + + meta[:cursor_pagination] + end + + def cursor_paginated? + cursor_pagination.present? + end end end diff --git a/lib/scalingo/faraday/unpack_middleware.rb b/lib/scalingo/faraday/unpack_middleware.rb new file mode 100644 index 0000000..c7fb3fe --- /dev/null +++ b/lib/scalingo/faraday/unpack_middleware.rb @@ -0,0 +1,33 @@ +require "faraday" + +module Scalingo + class UnpackMiddleware < Faraday::Middleware + def on_complete(env) + # We only want to unpack the response for successful responses + return unless env.response.success? + + # Only hash-like objects are relevant to "unpack" + return unless env.body.is_a?(Hash) + + # Extract meta from response + if env.body[:meta] + env[:response_meta] = env.body.delete(:meta) + end + + # Extract cursor-based pagination + if env.body.key?(:next_cursor) + env[:response_meta] = { + cursor_pagination: { + next_cursor: env.body.delete(:next_cursor), + has_more: env.body.delete(:has_more) + }.compact + } + end + + # Dig the root key if it's the only remaining key in the body + env.body = env.body.values.first if env.body.size == 1 + end + end +end + +Faraday::Response.register_middleware(unpack: Scalingo::UnpackMiddleware)