resolvedPath property

String get resolvedPath

Implementation

String get resolvedPath {
  final allParts = paramsFor(fullPath);

  if (allParts.isEmpty) {
    return fullPath.replaceFirst(RegExp(r'/$'), '');
  }

  final expandedParts = <String, List<int>>{
    for (final MapEntry(:key, value: count) in allParts.entries)
      key: switch (count) {
        1 => [],
        _ => List.generate(count, (index) => index + 1),
      },
  };

  Iterable<String> resolve() sync* {
    String replace(String path) {
      final params = paramsFor(path);

      if (params.isEmpty) {
        return path;
      }

      var updatedPath = path;

      for (final key in params.keys) {
        final count = expandedParts[key];
        assert(count != null, 'Param $key not found in $allParts');

        final replacement = switch (count) {
          [final int index, ...] => '$key$index',
          _ => key,
        }.toCamelCase();

        if (count case final List<int> count when count.isNotEmpty) {
          expandedParts[key] = count.sublist(1);
        }

        updatedPath = updatedPath.replaceAll(':$key', '\${$replacement}');
      }

      return updatedPath;
    }

    yield replace(parentPath);
    if (path case final String path) {
      yield replace(path);
    }
  }

  final resolved = resolve().join('/').replaceFirst(RegExp(r'/$'), '');

  return '/$resolved';
}