chcid method

Future<void> chcid(
  1. String path, {
  2. int? cidVersion,
  3. String? hash,
})

Changes the CID version/hash function of the node at path.

Matches Kubo files chcid: path must not be / and must resolve to a directory ("can only update directories"). With neither cidVersion nor hash given the call is a no-op. Supplying hash without cidVersion upgrades to CIDv1, matching Kubo's getPrefix.

Implementation

Future<void> chcid(String path, {int? cidVersion, String? hash}) async {
  final parts = _splitPath(path);
  if (parts.isEmpty) {
    throw Exception('Cannot change CID of MFS root');
  }
  // Kubo: no prefix options at all means the CID builder is nil and the
  // command changes nothing.
  if (cidVersion == null && hash == null) {
    return;
  }
  final hashType = hash ?? 'sha2-256';
  if (hashType != 'sha2-256') {
    throw UnsupportedError('Hash type $hashType not supported');
  }
  // A hash option without an explicit cid-version selects CIDv1.
  final targetVersion = cidVersion ?? 1;
  if (targetVersion != 0 && targetVersion != 1) {
    throw ArgumentError('Unsupported CID version: $targetVersion');
  }

  await _mutationLock.synchronized(() async {
    // Re-hash/re-encode the existing DAG with the requested settings.
    final currentCid = await _resolvePath(_rootCid!, parts);
    if (currentCid == null) {
      throw Exception('Path not found: $path');
    }
    final type = await _unixfsType(currentCid);
    if (type != Data_DataType.Directory && type != Data_DataType.HAMTShard) {
      throw Exception('can only update directories');
    }
    final newCid = await _rehashNode(currentCid, hashType, targetVersion);
    if (newCid == currentCid) {
      // No change
      return;
    }
    await _modifyPath(parts, (existingCid) async => newCid);
  });
}