run method

Run ulink resolve <url>. Returns the exit code + profile; does not call exit() itself so it stays unit-testable. 0 = resolved, 1 = not found / unreachable / API error, 2 = bad usage.

Implementation

Future<ResolveRunResult> run(ResolveOptions opts) async {
  if (opts.help) {
    _Log.out(resolveUsage);
    return ResolveRunResult(0, null);
  }

  final shortUrl = (opts.url ?? '').trim();
  if (shortUrl.isEmpty) {
    _Log.err('Missing the ULink short URL. Usage: `ulink resolve <url>` (see --help).');
    return ResolveRunResult(2, null);
  }

  final apiKey = opts.apiKey ?? Platform.environment['ULINK_API_KEY'];
  _Log.step('Resolving ${ConsoleStyle.bold(shortUrl)} via the live ULink edge');

  final r = await client.resolve(shortUrl, apiKey: apiKey);

  if (!r.ok) {
    if (r.status == 404) {
      _Log.err('Not found (404): no ULink domain or link matched ${ConsoleStyle.bold(shortUrl)}.');
      _Log.info(ConsoleStyle.dim('    Check the domain is a live ULink domain and the slug exists.'));
    } else if (r.status == 0) {
      _Log.err('Could not reach the ULink edge: ${r.error}');
    } else {
      _Log.err('Resolve failed (HTTP ${r.status}): ${r.error}');
    }
    if (opts.json) {
      _Log.out(const JsonEncoder.withIndent('  ').convert({
        'url': shortUrl,
        'ok': false,
        'status': r.status,
        'error': r.error,
      }));
    }
    return ResolveRunResult(1, null);
  }

  final profile = ResolveProfile.fromResolved(r.body);
  if (opts.json) {
    _Log.out(const JsonEncoder.withIndent('  ').convert({
      'url': shortUrl,
      'ok': true,
      'status': r.status,
      ...profile.toJson(),
    }));
  } else {
    _printHuman(shortUrl, profile);
  }
  return ResolveRunResult(0, profile);
}