register static method

bool register(
  1. String root,
  2. void register(
    1. String name,
    2. Object? handler(
      1. Object?
      )
    )
)

Registers the three bindings, confined to root.

Returns false where there is no filesystem to bind to, leaving the bindings unregistered rather than half-registered.

Implementation

static bool register(
  String root,
  void Function(String name, Object? Function(Object?) handler) register,
) {
  if (_registered) return true;

  final Directory directory = Directory(root);
  try {
    if (!directory.existsSync()) directory.createSync(recursive: true);
  } on FileSystemException {
    return false;
  }
  _root = directory.absolute.path;

  register('files.readBytes', (Object? arguments) {
    final File file = File(_resolve(_pathOf(arguments)));
    if (!file.existsSync()) {
      throw ArgumentError('files.readBytes: "${_pathOf(arguments)}" '
          'does not exist.');
    }
    return file.readAsBytesSync();
  });

  register('files.writeBytes', (Object? arguments) {
    final Map<Object?, Object?> map =
        arguments is Map ? arguments : const <Object?, Object?>{};
    final Object? bytes = map['bytes'];
    if (bytes is! List<int>) {
      // Refused rather than coerced. Writing the string form of a list is a
      // file that looks written and contains the wrong thing.
      throw ArgumentError(
        'files.writeBytes needs a List<int> in "bytes", got '
        '${bytes.runtimeType}.',
      );
    }
    final File file = File(_resolve(_pathOf(arguments)));
    file.parent.createSync(recursive: true);
    file.writeAsBytesSync(Uint8List.fromList(bytes), flush: true);
    // True, not the count. DVFiles.writeBytes asks through require<bool>, so
    // a count threw "returned int, expected bool" and made the binding
    // unusable on every target with a filesystem -- while the file on disk
    // was perfectly correct. files.delete beside it answers bool, and web
    // answers bool, so the count was the outlier as well as the fault.
    return true;
  });

  register('files.delete', (Object? arguments) {
    final File file = File(_resolve(_pathOf(arguments)));
    // Deleting what is not there is the caller's intent either way, and
    // throwing would make every caller wrap it.
    if (!file.existsSync()) return false;
    file.deleteSync();
    return true;
  });

  _registered = true;
  return true;
}