clean up some apis (#30)

- drop support for Uri objects in DirectoryDescriptor.load
- Use Object? instead of dynamic for `FileDescriptor` contents parameter
- Remove `parents` param in DirectoryDescriptor.load
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c2bc32..10a98c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,10 @@
 * Migrate to null safety.
 * Fix outdated URLs in `README.md`.
 * BREAKING: Removed archive support.
+* BREAKING: `DirectoryDescriptor.load` only supports a `String` path instead of
+  also accepting relative `Uri` objects.
+* BREAKING: `DirectoryDescriptor.load` no longer has an optional `parents`
+  parameter - this was intended for internal use only.
 
 ## 1.2.0
 
diff --git a/lib/src/directory_descriptor.dart b/lib/src/directory_descriptor.dart
index 0927667..a7e1d58 100644
--- a/lib/src/directory_descriptor.dart
+++ b/lib/src/directory_descriptor.dart
@@ -74,25 +74,14 @@
   }
 
   /// Treats this descriptor as a virtual filesystem and loads the binary
-  /// contents of the [FileDescriptor] at the given relative [url], which may be
-  /// a [Uri] or a [String].
-  ///
-  /// The [parents] parameter should only be passed by subclasses of
-  /// [DirectoryDescriptor] that are recursively calling [load]. It's the
-  /// URL-format path of the directories that have been loaded so far.
-  Stream<List<int>> load(url, [String? parents]) {
-    String path;
-    if (url is String) {
-      path = url;
-    } else if (url is Uri) {
-      path = url.toString();
-    } else {
-      throw ArgumentError.value(url, 'url', 'must be a Uri or a String.');
-    }
+  /// contents of the [FileDescriptor] at the given relative [path].
+  Stream<List<int>> load(String path) => _load(path);
 
+  /// Implementation of [load], tracks parents through recursive calls.
+  Stream<List<int>> _load(String path, [String? parents]) {
     if (!p.url.isWithin('.', path)) {
       throw ArgumentError.value(
-          url, 'url', 'must be relative and beneath the base URL.');
+          path, 'path', 'must be relative and beneath the base URL.');
     }
 
     return StreamCompleter.fromFuture(Future.sync(() {
@@ -117,7 +106,7 @@
           return (matchingEntries.first as FileDescriptor).readAsBytes();
         } else {
           return (matchingEntries.first as DirectoryDescriptor)
-              .load(p.url.joinAll(remainingPath), parentsAndSelf);
+              ._load(p.url.joinAll(remainingPath), parentsAndSelf);
         }
       }
     }));
diff --git a/lib/src/file_descriptor.dart b/lib/src/file_descriptor.dart
index f5d9216..b9eae6e 100644
--- a/lib/src/file_descriptor.dart
+++ b/lib/src/file_descriptor.dart
@@ -35,7 +35,7 @@
   ///
   /// To match a [Matcher] against a file's binary contents, use [new
   /// FileDescriptor.binaryMatcher] instead.
-  factory FileDescriptor(String name, contents) {
+  factory FileDescriptor(String name, Object? contents) {
     if (contents is String) return _StringFileDescriptor(name, contents);
     if (contents is List) {
       return _BinaryFileDescriptor(name, contents.cast<int>());