fromHttpResponse static method

Future<ApiCallResponse> fromHttpResponse(
  1. Response response,
  2. bool returnBody,
  3. bool decodeUtf8
)

Implementation

static Future<ApiCallResponse> fromHttpResponse(http.Response response, bool returnBody, bool decodeUtf8) async {
  var jsonBody;
  Pagination? pagination;
  ApiError? error;
  try {
    final responseBody = decodeUtf8 && returnBody ? const Utf8Decoder().convert(response.bodyBytes) : response.body;
    if (returnBody) {
      // Large payload (>1MB) → decode in isolate to avoid jank.
      // Smaller payloads → sync decode (isolate spawn overhead not worth it).
      if (response.bodyBytes.length > 1024 * 1024) {
        jsonBody = await compute(json.decode, responseBody);
      } else {
        jsonBody = json.decode(responseBody);
      }
    } else {
      jsonBody = null;
    }

    if (jsonBody is Map) {
      error =
          jsonBody["error"] != null
              ? ApiError.fromJson(jsonObject: jsonBody["error"])
              : (jsonBody["statusCode"] != null ? ApiError.fromJson(jsonObject: jsonBody) : null);

      // Pagination: formato standard {meta: {total, lastPage, currentPage, perPage}}
      if (jsonBody["meta"] != null) {
        pagination = Pagination.fromJson(jsonObject: jsonBody["meta"]);
      }
      // Pagination: formato HR {total, page, limit, totalPages} a livello root
      else if (jsonBody["total"] != null && jsonBody["items"] != null) {
        final p = Pagination();
        p.total = jsonBody['total'] as int?;
        p.currentPage = jsonBody['page'] as int?;
        p.perPage = jsonBody['limit'] as int?;
        p.lastPage = jsonBody['totalPages'] as int?;
        if (p.currentPage != null && p.currentPage! > 1) {
          p.prev = p.currentPage! - 1;
        }
        if (p.currentPage != null && p.lastPage != null && p.currentPage! < p.lastPage!) {
          p.next = p.currentPage! + 1;
        }
        pagination = p;
      }
    }
  } catch (_) {}

  // Estrae i dati: se è un Map usa "data" o "items", altrimenti body intero
  final extractedBody = jsonBody is Map
      ? (jsonBody["data"] ?? jsonBody["items"] ?? jsonBody)
      : jsonBody;

  return ApiCallResponse(
    extractedBody,
    pagination,
    error,
    response.headers,
    response.statusCode,
    response: response,
  );
}