toSdkPayload static method

Map<String, dynamic> toSdkPayload(
  1. Map<String, dynamic> link
)

Serialize our rich internal ULink link definition (see fdl_mapper.dart) into the real POST /sdk/links request body. Anything the ULink schema has no first-class field for (the in-app deep link, custom scheme, app ids, min versions, and all attribution params) rides along in parameters with allowQueryPassthrough so it is forwarded to the app on open — preserving routing intent and attribution end to end.

Implementation

static Map<String, dynamic> toSdkPayload(Map<String, dynamic> link) {
  final r = _m(link['routing']);
  final ios = _m(r['ios']);
  final android = _m(r['android']);
  final ipad = _m(ios['ipad']);
  final at = _m(link['attribution']);
  final utm = _m(at['utm']);
  final it = _m(at['itunes']);
  final social = _m(link['social']);
  final desktop = _m(r['desktop']);

  final iosUrl = ios['fallbackUrl'] ??
      (ios['appStoreId'] != null ? _appStoreUrl('${ios['appStoreId']}') : null);
  final androidUrl = android['fallbackUrl'] ??
      (android['packageName'] != null
          ? _playStoreUrl('${android['packageName']}')
          : null);
  final fallbackUrl = desktop['fallbackUrl'] ?? link['destination'];

  // Forwarded parameters: the deep link + everything not expressible up top.
  final parameters = _pruneEmpty({
    'deepLink': link['destination'],
    'iosBundleId': ios['bundleId'],
    'iosCustomScheme': ios['customScheme'],
    'iosMinimumVersion': ios['minVersion'],
    'iosIpadBundleId': ipad['bundleId'],
    'iosIpadFallbackUrl': ipad['fallbackUrl'],
    'androidPackageName': android['packageName'],
    'androidMinVersion': android['minVersion'],
    'forceRedirect': r['forceRedirect'] == true ? '1' : null,
    'utm_source': utm['source'],
    'utm_medium': utm['medium'],
    'utm_campaign': utm['campaign'],
    'utm_term': utm['term'],
    'utm_content': utm['content'],
    'gclid': at['gclid'],
    'at': it['at'],
    'ct': it['ct'],
    'mt': it['mt'],
    'pt': it['pt'],
  });

  final metadata = _pruneEmpty({
    'ogTitle': social['title'],
    'ogDescription': social['description'],
    'ogImage': social['imageUrl'],
  });

  return _pruneEmpty({
    'type': 'unified',
    'slug': link['slug'],
    'fallbackUrl': fallbackUrl,
    'iosUrl': iosUrl,
    'androidUrl': androidUrl,
    'allowQueryPassthrough': true,
    'parameters': parameters.isNotEmpty ? parameters : null,
    'metadata': metadata.isNotEmpty ? metadata : null,
  });
}