parse static method

Curl parse(
  1. String curlString
)

Parse curlString as a Curl class instance.

Example:

print(Curl.parse('curl -X GET https://www.example.com/')); // Curl(method: 'GET', url: 'https://www.example.com/')
print(Curl.parse('1f')); // [Exception] is thrown

Implementation

static Curl parse(String curlString) {
  final parser = ArgParser(allowTrailingOptions: true);

  // TODO: Add more options
  // https://gist.github.com/eneko/dc2d8edd9a4b25c5b0725dd123f98b10
  // Define the expected options
  parser.addOption('url');
  parser.addOption('request', abbr: 'X');
  parser.addMultiOption('header', abbr: 'H', splitCommas: false);
  parser.addOption('data', abbr: 'd');
  parser.addOption('cookie', abbr: 'b');
  parser.addOption('user', abbr: 'u');
  parser.addOption('referer', abbr: 'e');
  parser.addOption('user-agent', abbr: 'A');
  parser.addFlag('head', abbr: 'I');
  parser.addMultiOption('form', abbr: 'F');
  parser.addFlag('insecure', abbr: 'k');
  parser.addFlag('location', abbr: 'L');

  if (!curlString.startsWith('curl ')) {
    throw Exception("curlString doesn't start with 'curl '");
  }

  final splittedCurlString =
      splitAsCommandLineArgs(curlString.replaceFirst('curl ', ''));

  final result = parser.parse(splittedCurlString);

  // Extract the request headers
  Map<String, String>? headers;
  if (result['header'] != null) {
    final List<String> headersList = result['header'];
    if (headersList.isNotEmpty == true) {
      headers = <String, String>{};
      for (var headerString in headersList) {
        final splittedHeaderString = headerString.split(RegExp(r':\s*'));
        if (splittedHeaderString.length != 2) {
          throw Exception('Failed to split the `$headerString` header');
        }
        headers.addAll({splittedHeaderString[0]: splittedHeaderString[1]});
      }
    }
  }

  // Parse form data
  List<FormDataModel>? formData;
  if (result['form'] is List<String> &&
      (result['form'] as List<String>).isNotEmpty) {
    formData = <FormDataModel>[];
    for (final formEntry in result['form']) {
      final pairs = formEntry.split('=');
      if (pairs.length != 2) {
        throw Exception(
            'Form data entry $formEntry is not in key=value format');
      }

      // Handling the file or text type
      var formDataModel = pairs[1].startsWith('@')
          ? FormDataModel(
              name: pairs[0],
              value: pairs[1].substring(1),
              type: FormDataType.file,
            )
          : FormDataModel(
              name: pairs[0],
              value: pairs[1],
              type: FormDataType.text,
            );

      formData.add(formDataModel);
    }
    headers ??= <String, String>{};
    if (!(headers.containsKey(kHeaderContentType) ||
        headers.containsKey(kHeaderContentType.toLowerCase()))) {
      headers[kHeaderContentType] = "multipart/form-data";
    }
  }

  // Handle URL and query parameters
  final url = clean(result['url']) ?? clean(result.rest.firstOrNull);
  if (url == null) {
    throw Exception('URL is null');
  }
  final uri = Uri.parse(url);

  final method = result['head']
      ? 'HEAD'
      : ((result['request'] as String?)?.toUpperCase() ?? 'GET');
  final String? data = result['data'];
  final String? cookie = result['cookie'];
  final String? user = result['user'];
  final String? referer = result['referer'];
  final String? userAgent = result['user-agent'];
  final bool form = formData != null && formData.isNotEmpty;
  final bool insecure = result['insecure'] ?? false;
  final bool location = result['location'] ?? false;

  // Extract the request URL
  return Curl(
    method: method,
    uri: uri,
    headers: headers,
    data: data,
    cookie: cookie,
    user: user,
    referer: referer,
    userAgent: userAgent,
    form: form,
    formData: formData,
    insecure: insecure,
    location: location,
  );
}