request method

  1. @override
Future<ChalonaResponse> request(
  1. String url, {
  2. Map data = const {},
  3. String? token,
  4. List<ChalonaFile>? files,
  5. ChalonaHttpContentType contentType = ChalonaHttpContentType.json,
  6. ChalonaHttpMethod method = ChalonaHttpMethod.post,
})
override

Realiza una petición HTTP al servidor url - Ruta relativa a la URL base data - Datos a enviar en formato JSON token - Token de autenticación (opcional) files - Archivos a enviar (no implementado)

Throws:

Implementation

@override
Future<ChalonaResponse> request(
  String url, {
  Map data = const {},
  String? token,
  List<ChalonaFile>? files,
  ChalonaHttpContentType contentType = ChalonaHttpContentType.json,
  ChalonaHttpMethod method = ChalonaHttpMethod.post,
}) async {
  files ??= [];
  Map<String, String> headers = {
    'Content-Type': contentType.value,
    'Accept': contentType.value,
    if (token != null) 'Authorization': 'Bearer $token',
  };

  var chost = host;
  if (url.contains('https://') || url.contains('http://')) {
    chost = '';
  }
  var uri;
  if (method == ChalonaHttpMethod.get) {
    uri = Uri.parse(chost +
        url +
        (data.isNotEmpty
            ? '?' +
                Uri(
                        queryParameters: data.map(
                            (key, value) => MapEntry(key, value.toString())))
                    .query
            : ''));
  } else {
    uri = Uri.parse(chost + url);
  }

  Response response;
  if (method == ChalonaHttpMethod.get) {
    response = await get(uri, headers: headers);
  } else if (files.isNotEmpty) {
    // Uso de multipart/form-data para solicitudes con archivos
    var request = MultipartRequest('POST', uri);
    request.headers.addAll(headers);
    // Agregar archivos
    for (var file in files) {
      var multipartFile = MultipartFile.fromString(
        'xml',
        file.content,
        filename: file.fileName,
        contentType: MediaType('application', file.type),
      );
      request.files.add(multipartFile);
    }

    // Agregar argumentos
    request.fields
        .addAll(data.map((key, value) => MapEntry(key, value.toString())));

    var streamedResponse = await request.send();
    response = await Response.fromStream(streamedResponse);
  } else if (contentType == ChalonaHttpContentType.formUrlEncoded) {
    // Manejo especial para application/x-www-form-urlencoded
    Map<String, String> formData = {};
    data.forEach((key, value) {
      formData[key.toString()] = value.toString();
    });

    response = await post(
      uri,
      headers: headers,
      body: formData,
      encoding: Encoding.getByName('utf-8'),
    );
  } else {
    response = await post(
      uri,
      headers: headers,
      body: jsonEncode(data),
    );
  }

  ChalonaResponse r;
  try {
    // Intenta decodificar como JSON
    var decoded = jsonDecode(response.body);

    if (decoded is Map && decoded.containsKey('ok')) {
      r = ChalonaResponse(source: MapType.from(decoded));
    } else {
      r = ChalonaResponse(source: {'data': decoded});
    }
  } catch (e) {
    // Si no es JSON válido, trata como respuesta de texto
    r = ChalonaResponse(source: {
      'ok': response.statusCode == 200,
      'msg': response.statusCode == 200 ? '' : response.body,
      'data': response.statusCode == 200
          ? {
              'result': response.body,
            }
          : {}
    });
  }

  if (response.statusCode != 200 && response.statusCode != 201) {
    console.error(response.body);
    throw ChalonaResponse(source: {
      'ok': false,
      'msg': response.body,
      'data': {},
    });
  }

  return r;
}