var dbToCloud = (function (exports) {
  'use strict';

  function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);

    if (Object.getOwnPropertySymbols) {
      var symbols = Object.getOwnPropertySymbols(object);

      if (enumerableOnly) {
        symbols = symbols.filter(function (sym) {
          return Object.getOwnPropertyDescriptor(object, sym).enumerable;
        });
      }

      keys.push.apply(keys, symbols);
    }

    return keys;
  }

  function _objectSpread2(target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i] != null ? arguments[i] : {};

      if (i % 2) {
        ownKeys(Object(source), true).forEach(function (key) {
          _defineProperty(target, key, source[key]);
        });
      } else if (Object.getOwnPropertyDescriptors) {
        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
      } else {
        ownKeys(Object(source)).forEach(function (key) {
          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
        });
      }
    }

    return target;
  }

  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }

    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }

  function _asyncToGenerator(fn) {
    return function () {
      var self = this,
          args = arguments;
      return new Promise(function (resolve, reject) {
        var gen = fn.apply(self, args);

        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }

        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }

        _next(undefined);
      });
    };
  }

  function _defineProperty(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }

    return obj;
  }

  function _objectWithoutPropertiesLoose(source, excluded) {
    if (source == null) return {};
    var target = {};
    var sourceKeys = Object.keys(source);
    var key, i;

    for (i = 0; i < sourceKeys.length; i++) {
      key = sourceKeys[i];
      if (excluded.indexOf(key) >= 0) continue;
      target[key] = source[key];
    }

    return target;
  }

  function _objectWithoutProperties(source, excluded) {
    if (source == null) return {};

    var target = _objectWithoutPropertiesLoose(source, excluded);

    var key, i;

    if (Object.getOwnPropertySymbols) {
      var sourceSymbolKeys = Object.getOwnPropertySymbols(source);

      for (i = 0; i < sourceSymbolKeys.length; i++) {
        key = sourceSymbolKeys[i];
        if (excluded.indexOf(key) >= 0) continue;
        if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
        target[key] = source[key];
      }
    }

    return target;
  }

  function _slicedToArray(arr, i) {
    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
  }

  function _arrayWithHoles(arr) {
    if (Array.isArray(arr)) return arr;
  }

  function _iterableToArrayLimit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];

    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;

    var _s, _e;

    try {
      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
        _arr.push(_s.value);

        if (i && _arr.length === i) break;
      }
    } catch (err) {
      _d = true;
      _e = err;
    } finally {
      try {
        if (!_n && _i["return"] != null) _i["return"]();
      } finally {
        if (_d) throw _e;
      }
    }

    return _arr;
  }

  function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  }

  function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;

    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

    return arr2;
  }

  function _nonIterableRest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }

  function _createForOfIteratorHelper(o, allowArrayLike) {
    var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];

    if (!it) {
      if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
        if (it) o = it;
        var i = 0;

        var F = function () {};

        return {
          s: F,
          n: function () {
            if (i >= o.length) return {
              done: true
            };
            return {
              done: false,
              value: o[i++]
            };
          },
          e: function (e) {
            throw e;
          },
          f: F
        };
      }

      throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
    }

    var normalCompletion = true,
        didErr = false,
        err;
    return {
      s: function () {
        it = it.call(o);
      },
      n: function () {
        var step = it.next();
        normalCompletion = step.done;
        return step;
      },
      e: function (e) {
        didErr = true;
        err = e;
      },
      f: function () {
        try {
          if (!normalCompletion && it.return != null) it.return();
        } finally {
          if (didErr) throw err;
        }
      }
    };
  }

  function createLock({
    maxActiveReader = Infinity
  } = {}) {
    let firstTask;
    let lastTask;
    let activeReader = 0;
    const self = {
      read: fn => que(fn, false),
      write: fn => que(fn, true),
      length: 0
    };
    return self;

    function que(fn, block) {
      const task = createTask({
        fn,
        block
      });

      if (!lastTask) {
        firstTask = lastTask = task;
      } else {
        lastTask.next = task;
        task.prev = lastTask;
        lastTask = task;

        if (!firstTask) {
          firstTask = lastTask;
        }
      }

      self.length++;
      deque();
      return task.q.promise;
    }

    function defer() {
      const o = {};
      o.promise = new Promise((resolve, reject) => {
        o.resolve = resolve;
        o.reject = reject;
      });
      return o;
    }

    function createTask({
      fn,
      block = false,
      prev,
      next,
      q = defer(),
      q2 = fn.length ? defer() : null
    }) {
      return {
        fn,
        block,
        prev,
        next,
        q,
        q2
      };
    }

    function deque() {
      const task = firstTask;

      if (!task || task.block && task.prev || task.prev && task.prev.block || activeReader >= maxActiveReader) {
        return;
      }

      if (!task.block) {
        activeReader++;
      }

      firstTask = task.next;
      let result;

      try {
        result = task.fn(task.q2 && task.q2.resolve);
      } catch (err) {
        task.q.reject(err); // auto release with sync error
        // q2 is useless in this case

        onDone();
        return;
      }

      if (task.q2) {
        task.q2.promise.then(_onDone);
      }

      if (result && result.then) {
        const pending = result.then(task.q.resolve, task.q.reject);

        if (!task.q2) {
          pending.then(onDone);
        }
      } else {
        task.q.resolve(result);

        if (!task.q2) {
          // it's a sync function and you don't want to release it manually, why
          // do you need a lock?
          onDone();
          return;
        }
      }

      deque();

      function onDone() {
        _onDone();
      }

      function _onDone(afterDone) {
        if (task.prev) {
          task.prev.next = task.next;
        }

        if (task.next) {
          task.next.prev = task.prev;
        }

        if (lastTask === task) {
          lastTask = task.prev;
        }

        if (!task.block) {
          activeReader--;
        }

        self.length--;

        if (afterDone) {
          afterDone();
        }

        deque();
      }
    }
  }

  class LockError extends Error {
    constructor(expire) {
      super("The database is locked. Will expire at ".concat(new Date(expire).toLocaleString()));
      this.expire = expire;
      this.name = "LockError";

      if (Error.captureStackTrace) {
        Error.captureStackTrace(this, LockError);
      }
    }

  }

  function debounced(fn) {
    let timer = 0;
    let q;
    return () => {
      if (timer) {
        clearTimeout(timer);
      }

      timer = setTimeout(run);

      if (!q) {
        q = defer();
      }

      return q.promise;
    };

    function run() {
      Promise.resolve(fn()).then(q.resolve, q.reject);
      timer = 0;
      q = null;
    }

    function defer() {
      const o = {};
      o.promise = new Promise((resolve, reject) => {
        o.resolve = resolve;
        o.reject = reject;
      });
      return o;
    }
  }

  function delay(time) {
    return new Promise(resolve => setTimeout(resolve, time));
  }

  function buildDrive(_drive) {
    const drive = Object.create(_drive);

    drive.get = /*#__PURE__*/function () {
      var _ref = _asyncToGenerator(function* (path) {
        return JSON.parse(yield _drive.get(path));
      });

      return function (_x) {
        return _ref.apply(this, arguments);
      };
    }();

    drive.put = /*#__PURE__*/function () {
      var _ref2 = _asyncToGenerator(function* (path, data) {
        return yield _drive.put(path, JSON.stringify(data));
      });

      return function (_x2, _x3) {
        return _ref2.apply(this, arguments);
      };
    }();

    drive.post = /*#__PURE__*/function () {
      var _ref3 = _asyncToGenerator(function* (path, data) {
        return yield _drive.post(path, JSON.stringify(data));
      });

      return function (_x4, _x5) {
        return _ref3.apply(this, arguments);
      };
    }();

    drive.isInit = false;

    if (!drive.acquireLock) {
      drive.acquireLock = acquireLock;
      drive.releaseLock = releaseLock;
    }

    if (!drive.getMeta) {
      drive.getMeta = getMeta;
      drive.putMeta = putMeta;
    }

    if (!drive.peekChanges) {
      drive.peekChanges = peekChanges;
    }

    return drive;

    function acquireLock(_x6) {
      return _acquireLock.apply(this, arguments);
    }

    function _acquireLock() {
      _acquireLock = _asyncToGenerator(function* (expire) {
        try {
          yield this.post("lock.json", {
            expire: Date.now() + expire * 60 * 1000
          });
        } catch (err) {
          if (err.code !== "EEXIST") {
            throw err;
          }

          const data = yield this.get("lock.json");

          if (Date.now() > data.expire) {
            // FIXME: this may delete a different lock created by other instances
            yield this.delete("lock.json");
            throw new Error("Found expired lock, please try again");
          }

          throw new LockError(data.expire);
        }
      });
      return _acquireLock.apply(this, arguments);
    }

    function releaseLock() {
      return _releaseLock.apply(this, arguments);
    }

    function _releaseLock() {
      _releaseLock = _asyncToGenerator(function* () {
        yield this.delete("lock.json");
      });
      return _releaseLock.apply(this, arguments);
    }

    function getMeta() {
      return _getMeta.apply(this, arguments);
    }

    function _getMeta() {
      _getMeta = _asyncToGenerator(function* () {
        try {
          return yield this.get("meta.json");
        } catch (err) {
          if (err.code === "ENOENT" || err.code === 404) {
            return {};
          }

          throw err;
        }
      });
      return _getMeta.apply(this, arguments);
    }

    function putMeta(_x7) {
      return _putMeta.apply(this, arguments);
    }

    function _putMeta() {
      _putMeta = _asyncToGenerator(function* (data) {
        yield this.put("meta.json", data);
      });
      return _putMeta.apply(this, arguments);
    }

    function peekChanges(_x8) {
      return _peekChanges.apply(this, arguments);
    }

    function _peekChanges() {
      _peekChanges = _asyncToGenerator(function* (oldMeta) {
        const newMeta = yield this.getMeta();
        return newMeta.lastChange !== oldMeta.lastChange;
      });
      return _peekChanges.apply(this, arguments);
    }
  }

  function dbToCloud({
    onGet,
    onPut,
    onDelete,
    onFirstSync,
    onWarn = console.error,
    onProgress,
    compareRevision,
    getState,
    setState,
    lockExpire = 60,
    retryMaxAttempts = 5,
    retryExp = 1.5,
    retryDelay = 10
  }) {
    let _drive2;

    let state;
    let meta;
    const changeCache = new Map();
    const saveState = debounced(() => setState(_drive2, state));
    const revisionCache = new Map();
    const lock = createLock();
    return {
      use,
      init,
      uninit,
      put,
      delete: delete_,
      syncNow,
      drive: () => _drive2,
      isInit: () => Boolean(state && state.enabled)
    };

    function use(newDrive) {
      _drive2 = buildDrive(newDrive);
    }

    function init() {
      return lock.write( /*#__PURE__*/_asyncToGenerator(function* () {
        if (state && state.enabled) {
          return;
        }

        if (!_drive2) {
          throw new Error("cloud drive is undefined");
        }

        state = (yield getState(_drive2)) || {};
        state.enabled = true;

        if (!state.queue) {
          state.queue = [];
        }
      }));
    }

    function uninit() {
      return lock.write( /*#__PURE__*/_asyncToGenerator(function* () {
        if (!state || !state.enabled) {
          return;
        }

        state = meta = null;
        changeCache.clear();
        revisionCache.clear();

        if (_drive2.uninit && _drive2.isInit) {
          yield _drive2.uninit();
          _drive2.isInit = false;
        }

        yield saveState();
      }));
    }

    function syncPull() {
      return _syncPull.apply(this, arguments);
    }

    function _syncPull() {
      _syncPull = _asyncToGenerator(function* () {
        meta = yield _drive2.getMeta();

        if (!meta.lastChange || meta.lastChange === state.lastChange) {
          // nothing changes
          return;
        }

        let changes = [];

        if (!state.lastChange) {
          // pull everything
          changes = (yield _drive2.list("docs")).map(name => ({
            action: 'put',
            _id: name.slice(0, -5)
          }));
        } else {
          const end = Math.floor((meta.lastChange - 1) / 100); // inclusive end

          let i = Math.floor(state.lastChange / 100);

          while (i <= end) {
            const newChanges = yield _drive2.get("changes/".concat(i, ".json"));
            changeCache.set(i, newChanges);
            changes = changes.concat(newChanges);
            i++;
          }

          changes = changes.slice(state.lastChange % 100);
        } // merge changes


        const idx = new Map();

        var _iterator = _createForOfIteratorHelper(changes),
            _step;

        try {
          for (_iterator.s(); !(_step = _iterator.n()).done;) {
            const change = _step.value;
            idx.set(change._id, change);
          }
        } catch (err) {
          _iterator.e(err);
        } finally {
          _iterator.f();
        }

        let loaded = 0;

        var _iterator2 = _createForOfIteratorHelper(idx),
            _step2;

        try {
          for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
            const _step2$value = _slicedToArray(_step2.value, 2),
                  id = _step2$value[0],
                  change = _step2$value[1];

            let doc, _rev;

            if (onProgress) {
              onProgress({
                phase: 'pull',
                total: idx.size,
                loaded,
                change
              });
            }

            if (change.action === "delete") {
              yield onDelete(id, change._rev);
            } else if (change.action === "put") {
              try {
                var _yield$_drive2$get = yield _drive2.get("docs/".concat(id, ".json"));

                doc = _yield$_drive2$get.doc;
                _rev = _yield$_drive2$get._rev;
              } catch (err) {
                if (err.code === "ENOENT" || err.code === 404) {
                  onWarn("Cannot find ".concat(id, ". Is it deleted without updating the history?"));
                  loaded++;
                  continue;
                }

                throw err;
              }

              yield onPut(doc);
            } // record the remote revision


            const rev = change._rev || _rev;

            if (rev) {
              revisionCache.set(id, rev);
            }

            loaded++;
          }
        } catch (err) {
          _iterator2.e(err);
        } finally {
          _iterator2.f();
        }

        state.lastChange = meta.lastChange;
        yield saveState();
      });
      return _syncPull.apply(this, arguments);
    }

    function syncPush() {
      return _syncPush.apply(this, arguments);
    }

    function _syncPush() {
      _syncPush = _asyncToGenerator(function* () {
        if (!state.queue.length) {
          // nothing to push
          return;
        } // snapshot


        const changes = state.queue.slice(); // merge changes

        const idx = new Map();

        var _iterator3 = _createForOfIteratorHelper(changes),
            _step3;

        try {
          for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
            const change = _step3.value;
            idx.set(change._id, change);
          } // drop outdated change

        } catch (err) {
          _iterator3.e(err);
        } finally {
          _iterator3.f();
        }

        const newChanges = [];

        var _iterator4 = _createForOfIteratorHelper(idx.values()),
            _step4;

        try {
          for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
            const change = _step4.value;
            // FIXME: is it safe to assume that the local doc is newer when
            // remoteRev is undefined?
            const remoteRev = revisionCache.get(change._id);

            if (remoteRev !== undefined && compareRevision(change._rev, remoteRev) <= 0) {
              continue;
            }

            newChanges.push(change);
          } // FIXME: there should be no need to push data when !newChanges.length
          // start pushing

        } catch (err) {
          _iterator4.e(err);
        } finally {
          _iterator4.f();
        }

        let loaded = 0;

        for (var _i = 0, _newChanges = newChanges; _i < _newChanges.length; _i++) {
          const change = _newChanges[_i];

          if (onProgress) {
            onProgress({
              phase: 'push',
              loaded,
              total: newChanges.length,
              change
            });
          }

          if (change.action === "delete") {
            yield _drive2.delete("docs/".concat(change._id, ".json"));
          } else if (change.action === "put") {
            const doc = yield onGet(change._id, change._rev);
            yield _drive2.put("docs/".concat(change._id, ".json"), {
              doc,
              _rev: change._rev
            });
          }

          revisionCache.set(change._id, change._rev);
          loaded++;
        } // push changes


        let lastChanges;
        let index; // meta is already pulled in syncPull

        if (meta.lastChange) {
          index = Math.floor(meta.lastChange / 100);
          const len = meta.lastChange % 100;
          lastChanges = len ? changeCache.get(index) || (yield _drive2.get("changes/".concat(index, ".json"))) : []; // it is possible that JSON data contains more records defined by
          // meta.lastChange

          lastChanges = lastChanges.slice(0, len).concat(newChanges);
        } else {
          // first sync
          index = 0;
          lastChanges = newChanges;
        }

        for (let i = 0; i * 100 < lastChanges.length; i++) {
          const window = lastChanges.slice(i * 100, (i + 1) * 100);
          yield _drive2.put("changes/".concat(index + i, ".json"), window);
          changeCache.set(index + i, window);
        }

        meta.lastChange = (meta.lastChange || 0) + newChanges.length;
        yield _drive2.putMeta(meta);
        state.queue = state.queue.slice(changes.length);
        state.lastChange = meta.lastChange;
        yield saveState();
      });
      return _syncPush.apply(this, arguments);
    }

    function sync() {
      return _sync.apply(this, arguments);
    }

    function _sync() {
      _sync = _asyncToGenerator(function* () {
        let tried = 0;
        let wait = retryDelay;
        let lastErr;

        while (true) {
          // eslint-disable-line no-constant-condition
          try {
            yield _drive2.acquireLock(lockExpire);
            break;
          } catch (err) {
            if (err.name !== "LockError") {
              throw err;
            }

            lastErr = err;
          }

          tried++;

          if (tried >= retryMaxAttempts) {
            throw lastErr;
          }

          yield delay(wait * 1000);
          wait *= retryExp;
        }

        try {
          yield syncPull();
          yield syncPush();
        } finally {
          yield _drive2.releaseLock();
        }
      });
      return _sync.apply(this, arguments);
    }

    function syncNow(peek) {
      return lock.write( /*#__PURE__*/_asyncToGenerator(function* () {
        if (!state || !state.enabled) {
          throw new Error("Cannot sync now, the sync is not enabled");
        }

        if (_drive2.init && !_drive2.isInit) {
          yield _drive2.init();
          _drive2.isInit = true;
        }

        if (state.lastChange == null) {
          yield onFirstSync();
        }

        yield _syncNow(peek);
      }));
    }

    function _syncNow() {
      return _syncNow2.apply(this, arguments);
    }

    function _syncNow2() {
      _syncNow2 = _asyncToGenerator(function* (peek = true) {
        if (onProgress) {
          onProgress({
            phase: 'start'
          });
        }

        try {
          if (!state.queue.length && peek && meta) {
            const changed = yield _drive2.peekChanges(meta);

            if (!changed) {
              return;
            }
          }

          yield sync();
        } finally {
          if (onProgress) {
            onProgress({
              phase: 'end'
            });
          }
        }
      });
      return _syncNow2.apply(this, arguments);
    }

    function put(_id, _rev) {
      if (!state || !state.enabled) {
        return;
      }

      state.queue.push({
        _id,
        _rev,
        action: "put"
      });
      saveState();
    }

    function delete_(_id, _rev) {
      if (!state || !state.enabled) {
        return;
      }

      state.queue.push({
        _id,
        _rev,
        action: "delete"
      });
      saveState();
    }
  }

  var empty = (() => {});

  function percentToByte(p) {
    return String.fromCharCode(parseInt(p.slice(1), 16));
  }

  function encode(str) {
    return btoa(encodeURIComponent(str).replace(/%[0-9A-F]{2}/g, percentToByte));
  }

  function byteToPercent(b) {
    return "%".concat("00".concat(b.charCodeAt(0).toString(16)).slice(-2));
  }

  function decode(str) {
    return decodeURIComponent(Array.from(atob(str), byteToPercent).join(""));
  }

  const _excluded$2 = ["path", "contentType", "headers", "format", "raw"];

  class RequestError extends Error {
    constructor(message, origin, code = origin && origin.status) {
      super(message);
      this.code = code;
      this.origin = origin;

      if (Error.captureStackTrace) {
        Error.captureStackTrace(this, RequestError);
      }
    }

  }

  function createRequest({
    fetch,
    cooldown = 0,
    getAccessToken,
    username,
    password
  }) {
    const lock = createLock();
    const basicAuth = username || password ? "Basic ".concat(encode("".concat(username, ":").concat(password))) : null;
    return args => {
      return lock.write( /*#__PURE__*/function () {
        var _ref = _asyncToGenerator(function* (done) {
          try {
            return yield doRequest(args);
          } finally {
            if (!cooldown || !args.method || args.method === "GET") {
              done();
            } else {
              setTimeout(done, cooldown);
            }
          }
        });

        return function (_x) {
          return _ref.apply(this, arguments);
        };
      }());
    };

    function doRequest(_x2) {
      return _doRequest.apply(this, arguments);
    }

    function _doRequest() {
      _doRequest = _asyncToGenerator(function* (_ref2) {
        let path = _ref2.path,
            contentType = _ref2.contentType,
            _headers = _ref2.headers,
            format = _ref2.format,
            _ref2$raw = _ref2.raw,
            raw = _ref2$raw === void 0 ? false : _ref2$raw,
            args = _objectWithoutProperties(_ref2, _excluded$2);

        const headers = {};

        if (getAccessToken) {
          headers["Authorization"] = "Bearer ".concat(yield getAccessToken());
        }

        if (basicAuth) {
          headers["Authorization"] = basicAuth;
        }

        if (contentType) {
          headers["Content-Type"] = contentType;
        }

        Object.assign(headers, _headers);

        while (true) {
          // eslint-disable-line no-constant-condition
          // console.log("req", path, args, headers);
          const res = yield fetch(path, _objectSpread2({
            headers
          }, args)); // console.log("res", path, args, res.status, headers);

          if (!res.ok) {
            const retry = res.headers.get("Retry-After");

            if (retry) {
              const time = Number(retry);

              if (time) {
                yield delay(time * 1000);
                continue;
              }
            }

            const text = yield res.text();
            throw new RequestError("failed to fetch [".concat(res.status, "]: ").concat(text), res);
          }

          if (raw) {
            return res;
          }

          if (format) {
            return yield res[format]();
          }

          const resContentType = res.headers.get("Content-Type");

          if (/application\/json/.test(resContentType)) {
            return yield res.json();
          }

          return yield res.text();
        }
      });
      return _doRequest.apply(this, arguments);
    }
  }

  function createDrive$4({
    userAgent = "db-to-cloud",
    owner,
    repo,
    getAccessToken,
    fetch = (typeof self !== "undefined" ? self : global).fetch
  }) {
    const request = createRequest({
      fetch,
      getAccessToken,
      cooldown: 1000
    });
    const shaCache = new Map();
    return {
      name: "github",
      get,
      put,
      post,
      delete: delete_,
      list,
      shaCache
    };

    function requestAPI(args) {
      if (!args.headers) {
        args.headers = {};
      }

      if (!args.headers["User-Agent"]) {
        args.headers["User-Agent"] = userAgent;
      }

      if (!args.headers["Accept"]) {
        args.headers["Accept"] = "application/vnd.github.v3+json";
      }

      args.path = "https://api.github.com".concat(args.path);
      return request(args);
    }

    function list(_x) {
      return _list.apply(this, arguments);
    }

    function _list() {
      _list = _asyncToGenerator(function* (file) {
        // FIXME: This API has an upper limit of 1,000 files for a directory. If you need to retrieve more files, use the Git Trees API.
        const result = yield requestAPI({
          path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file)
        });
        const names = [];

        var _iterator = _createForOfIteratorHelper(result),
            _step;

        try {
          for (_iterator.s(); !(_step = _iterator.n()).done;) {
            const item = _step.value;
            names.push(item.name);
            shaCache.set(item.path, item.sha);
          }
        } catch (err) {
          _iterator.e(err);
        } finally {
          _iterator.f();
        }

        return names;
      });
      return _list.apply(this, arguments);
    }

    function get(_x2) {
      return _get.apply(this, arguments);
    }

    function _get() {
      _get = _asyncToGenerator(function* (file) {
        // FIXME: This API supports files up to 1 megabyte in size.
        const result = yield requestAPI({
          path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file)
        });
        shaCache.set(result.path, result.sha);
        return decode(result.content);
      });
      return _get.apply(this, arguments);
    }

    function put(_x3, _x4) {
      return _put.apply(this, arguments);
    }

    function _put() {
      _put = _asyncToGenerator(function* (file, data, overwrite = true) {
        const params = {
          message: "",
          content: encode(data)
        };

        if (overwrite && shaCache.has(file)) {
          params.sha = shaCache.get(file);
        }

        const args = {
          method: "PUT",
          path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file),
          contentType: "application/json",
          body: JSON.stringify(params)
        };
        let retried = false;
        let result;

        while (!result) {
          try {
            result = yield requestAPI(args);
          } catch (err) {
            if (err.code !== 422 || !err.message.includes("\\\"sha\\\" wasn't supplied")) {
              throw err;
            }

            if (!overwrite || retried) {
              err.code = "EEXIST";
              throw err;
            }

            yield get(file);
          }

          retried = true;
        }

        shaCache.set(file, result.content.sha);
      });
      return _put.apply(this, arguments);
    }

    function post(file, data) {
      return put(file, data, false);
    }

    function delete_(_x5) {
      return _delete_.apply(this, arguments);
    }

    function _delete_() {
      _delete_ = _asyncToGenerator(function* (file) {
        try {
          let sha = shaCache.get(file);

          if (!sha) {
            yield get(file);
            sha = shaCache.get(file);
          }

          yield requestAPI({
            method: "DELETE",
            path: "/repos/".concat(owner, "/").concat(repo, "/contents/").concat(file),
            body: JSON.stringify({
              message: "",
              sha
            })
          });
        } catch (err) {
          if (err.code === 404) {
            return;
          } // FIXME: do we have to handle 422 errors?


          throw err;
        }
      });
      return _delete_.apply(this, arguments);
    }
  }

  const _excluded$1 = ["path", "body"];

  function createDrive$3({
    getAccessToken,
    fetch = (typeof self !== "undefined" ? self : global).fetch
  }) {
    const request = createRequest({
      fetch,
      getAccessToken
    });
    return {
      name: "dropbox",
      get,
      put,
      post,
      delete: delete_,
      list
    };

    function requestRPC(_ref) {
      let path = _ref.path,
          body = _ref.body,
          args = _objectWithoutProperties(_ref, _excluded$1);

      return request(_objectSpread2({
        method: "POST",
        path: "https://api.dropboxapi.com/2/".concat(path),
        contentType: "application/json",
        body: JSON.stringify(body)
      }, args));
    }

    function list(_x) {
      return _list.apply(this, arguments);
    }

    function _list() {
      _list = _asyncToGenerator(function* (file) {
        const names = [];
        let result = yield requestRPC({
          path: "files/list_folder",
          body: {
            path: "/".concat(file)
          }
        });

        var _iterator = _createForOfIteratorHelper(result.entries),
            _step;

        try {
          for (_iterator.s(); !(_step = _iterator.n()).done;) {
            const entry = _step.value;
            names.push(entry.name);
          }
        } catch (err) {
          _iterator.e(err);
        } finally {
          _iterator.f();
        }

        if (!result.has_more) {
          return names;
        }

        while (result.has_more) {
          result = yield requestRPC({
            path: "files/list_folder/continue",
            body: {
              cursor: result.cursor
            }
          });

          var _iterator2 = _createForOfIteratorHelper(result.entries),
              _step2;

          try {
            for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
              const entry = _step2.value;
              names.push(entry.name);
            }
          } catch (err) {
            _iterator2.e(err);
          } finally {
            _iterator2.f();
          }
        }

        return names;
      });
      return _list.apply(this, arguments);
    }

    function stringifyParams(obj) {
      const params = new URLSearchParams();
      params.set("arg", JSON.stringify(obj));
      return params.toString();
    }

    function get(_x2) {
      return _get.apply(this, arguments);
    }

    function _get() {
      _get = _asyncToGenerator(function* (file) {
        const params = {
          path: "/".concat(file)
        };

        try {
          return yield request({
            path: "https://content.dropboxapi.com/2/files/download?".concat(stringifyParams(params)),
            format: "text"
          });
        } catch (err) {
          if (err.code === 409 && err.message.includes("not_found")) {
            err.code = "ENOENT";
          }

          throw err;
        }
      });
      return _get.apply(this, arguments);
    }

    function put(_x3, _x4) {
      return _put.apply(this, arguments);
    }

    function _put() {
      _put = _asyncToGenerator(function* (file, data, mode = "overwrite") {
        const params = {
          path: "/".concat(file),
          mode,
          autorename: false,
          mute: true
        };
        yield request({
          path: "https://content.dropboxapi.com/2/files/upload?".concat(stringifyParams(params)),
          method: "POST",
          contentType: "application/octet-stream",
          body: data
        });
      });
      return _put.apply(this, arguments);
    }

    function post(_x5, _x6) {
      return _post.apply(this, arguments);
    }

    function _post() {
      _post = _asyncToGenerator(function* (file, data) {
        try {
          return yield put(file, data, "add");
        } catch (err) {
          if (err.code === 409 && err.message.includes("conflict")) {
            err.code = "EEXIST";
          }

          throw err;
        }
      });
      return _post.apply(this, arguments);
    }

    function delete_(_x7) {
      return _delete_.apply(this, arguments);
    }

    function _delete_() {
      _delete_ = _asyncToGenerator(function* (file) {
        try {
          yield requestRPC({
            path: "files/delete_v2",
            body: {
              path: "/".concat(file)
            }
          });
        } catch (err) {
          if (err.code === 409 && err.message.includes("not_found")) {
            return;
          }

          throw err;
        }
      });
      return _delete_.apply(this, arguments);
    }
  }

  function createDrive$2({
    getAccessToken,
    fetch = (typeof self !== "undefined" ? self : global).fetch
  }) {
    const request = createRequest({
      fetch,
      getAccessToken
    });
    return {
      name: "onedrive",
      get,
      put,
      post,
      delete: delete_,
      list
    };

    function query(_x) {
      return _query.apply(this, arguments);
    }

    function _query() {
      _query = _asyncToGenerator(function* (args) {
        args.path = "https://graph.microsoft.com/v1.0/me/drive/special/approot".concat(args.path);
        return yield request(args);
      });
      return _query.apply(this, arguments);
    }

    function list(_x2) {
      return _list.apply(this, arguments);
    }

    function _list() {
      _list = _asyncToGenerator(function* (file) {
        if (file) {
          file = ":/".concat(file, ":");
        }

        let result = yield query({
          path: "".concat(file, "/children?select=name")
        });
        let files = result.value.map(i => i.name);

        while (result["@odata.nextLink"]) {
          result = yield request({
            path: result["@odata.nextLink"]
          });
          files = files.concat(result.value.map(i => i.name));
        }

        return files;
      });
      return _list.apply(this, arguments);
    }

    function get(_x3) {
      return _get.apply(this, arguments);
    }

    function _get() {
      _get = _asyncToGenerator(function* (file) {
        return yield query({
          path: ":/".concat(file, ":/content"),
          format: "text"
        });
      });
      return _get.apply(this, arguments);
    }

    function put(_x4, _x5) {
      return _put.apply(this, arguments);
    }

    function _put() {
      _put = _asyncToGenerator(function* (file, data) {
        yield query({
          method: "PUT",
          path: ":/".concat(file, ":/content"),
          headers: {
            "Content-Type": "text/plain"
          },
          body: data
        });
      });
      return _put.apply(this, arguments);
    }

    function post(_x6, _x7) {
      return _post.apply(this, arguments);
    }

    function _post() {
      _post = _asyncToGenerator(function* (file, data) {
        try {
          yield query({
            method: "PUT",
            path: ":/".concat(file, ":/content?@microsoft.graph.conflictBehavior=fail"),
            headers: {
              "Content-Type": "text/plain"
            },
            body: data
          });
        } catch (err) {
          if (err.code === 409 && err.message.includes("nameAlreadyExists")) {
            err.code = "EEXIST";
          }

          throw err;
        }
      });
      return _post.apply(this, arguments);
    }

    function delete_(_x8) {
      return _delete_.apply(this, arguments);
    }

    function _delete_() {
      _delete_ = _asyncToGenerator(function* (file) {
        try {
          yield query({
            method: "DELETE",
            path: ":/".concat(file, ":")
          });
        } catch (err) {
          if (err.code === 404) {
            return;
          }

          throw err;
        }
      });
      return _delete_.apply(this, arguments);
    }
  }

  function createDrive$1({
    getAccessToken,
    fetch = (typeof self !== "undefined" ? self : global).fetch,
    FormData = (typeof self !== "undefined" ? self : global).FormData,
    Blob = (typeof self !== "undefined" ? self : global).Blob
  }) {
    const request = createRequest({
      fetch,
      getAccessToken
    });
    const fileMetaCache = new Map();
    let lockRev;
    return {
      name: "google",
      get,
      put,
      post,
      delete: delete_,
      list,
      init,
      acquireLock,
      releaseLock,
      fileMetaCache
    };

    function revDelete(_x, _x2) {
      return _revDelete.apply(this, arguments);
    }

    function _revDelete() {
      _revDelete = _asyncToGenerator(function* (fileId, revId) {
        yield request({
          method: "DELETE",
          path: "https://www.googleapis.com/drive/v3/files/".concat(fileId, "/revisions/").concat(revId)
        });
      });
      return _revDelete.apply(this, arguments);
    }

    function acquireLock(_x3) {
      return _acquireLock.apply(this, arguments);
    }

    function _acquireLock() {
      _acquireLock = _asyncToGenerator(function* (expire) {
        const lock = fileMetaCache.get("lock.json");

        const _yield$queryPatch = yield queryPatch(lock.id, JSON.stringify({
          expire: Date.now() + expire * 60 * 1000
        })),
              headRevisionId = _yield$queryPatch.headRevisionId;

        const result = yield request({
          path: "https://www.googleapis.com/drive/v3/files/".concat(lock.id, "/revisions?fields=revisions(id)")
        });

        for (let i = 1; i < result.revisions.length; i++) {
          const revId = result.revisions[i].id;

          if (revId === headRevisionId) {
            // success
            lockRev = headRevisionId;
            return;
          }

          const rev = JSON.parse(yield request({
            path: "https://www.googleapis.com/drive/v3/files/".concat(lock.id, "/revisions/").concat(revId, "?alt=media")
          }));

          if (rev.expire > Date.now()) {
            // failed, delete the lock
            yield revDelete(lock.id, headRevisionId);
            throw new LockError(rev.expire);
          } // delete outdated lock


          yield revDelete(lock.id, revId);
        }

        throw new Error("cannot find lock revision");
      });
      return _acquireLock.apply(this, arguments);
    }

    function releaseLock() {
      return _releaseLock.apply(this, arguments);
    }

    function _releaseLock() {
      _releaseLock = _asyncToGenerator(function* () {
        const lock = fileMetaCache.get("lock.json");
        yield revDelete(lock.id, lockRev);
        lockRev = null;
      });
      return _releaseLock.apply(this, arguments);
    }

    function queryList(_x4, _x5) {
      return _queryList.apply(this, arguments);
    }

    function _queryList() {
      _queryList = _asyncToGenerator(function* (path, onPage) {
        path = "https://www.googleapis.com/drive/v3/files?spaces=appDataFolder&fields=nextPageToken,files(id,name,headRevisionId)" + (path ? "&" + path : "");
        let result = yield request({
          path
        });
        onPage(result);

        while (result.nextPageToken) {
          result = yield request({
            path: "".concat(path, "&pageToken=").concat(result.nextPageToken)
          });
          onPage(result);
        }
      });
      return _queryList.apply(this, arguments);
    }

    function queryPatch(_x6, _x7) {
      return _queryPatch.apply(this, arguments);
    }

    function _queryPatch() {
      _queryPatch = _asyncToGenerator(function* (id, text) {
        return yield request({
          method: "PATCH",
          path: "https://www.googleapis.com/upload/drive/v3/files/".concat(id, "?uploadType=media&fields=headRevisionId"),
          headers: {
            "Content-Type": "text/plain"
          },
          body: text
        });
      });
      return _queryPatch.apply(this, arguments);
    }

    function updateMeta(_x8) {
      return _updateMeta.apply(this, arguments);
    }

    function _updateMeta() {
      _updateMeta = _asyncToGenerator(function* (query) {
        if (query) {
          query = "q=".concat(encodeURIComponent(query));
        }

        yield queryList(query, result => {
          var _iterator = _createForOfIteratorHelper(result.files),
              _step;

          try {
            for (_iterator.s(); !(_step = _iterator.n()).done;) {
              const file = _step.value;
              fileMetaCache.set(file.name, file);
            }
          } catch (err) {
            _iterator.e(err);
          } finally {
            _iterator.f();
          }
        });
      });
      return _updateMeta.apply(this, arguments);
    }

    function init() {
      return _init.apply(this, arguments);
    }

    function _init() {
      _init = _asyncToGenerator(function* () {
        yield updateMeta();

        if (!fileMetaCache.has("lock.json")) {
          yield post("lock.json", "{}");
        }

        if (!fileMetaCache.has("meta.json")) {
          yield post("meta.json", "{}");
        }
      });
      return _init.apply(this, arguments);
    }

    function list(_x9) {
      return _list.apply(this, arguments);
    }

    function _list() {
      _list = _asyncToGenerator(function* (file) {
        // FIXME: this only works if file is a single dir
        // FIXME: this only works if the list method is called right after init, use
        // queryList instead?
        return [...fileMetaCache.values()].filter(f => f.name.startsWith(file + "/")).map(f => f.name.split("/")[1]);
      });
      return _list.apply(this, arguments);
    }

    function get(_x10) {
      return _get.apply(this, arguments);
    }

    function _get() {
      _get = _asyncToGenerator(function* (file) {
        let meta = fileMetaCache.get(file);

        if (!meta) {
          yield updateMeta("name = '".concat(file, "'"));
          meta = fileMetaCache.get(file);

          if (!meta) {
            throw new RequestError("metaCache doesn't contain ".concat(file), null, "ENOENT");
          }
        }

        try {
          return yield request({
            path: "https://www.googleapis.com/drive/v3/files/".concat(meta.id, "?alt=media")
          });
        } catch (err) {
          if (err.code === 404) {
            err.code = "ENOENT";
          }

          throw err;
        }
      });
      return _get.apply(this, arguments);
    }

    function put(_x11, _x12) {
      return _put.apply(this, arguments);
    }

    function _put() {
      _put = _asyncToGenerator(function* (file, data) {
        if (!fileMetaCache.has(file)) {
          return yield post(file, data);
        }

        const meta = fileMetaCache.get(file);
        const result = yield queryPatch(meta.id, data);
        meta.headRevisionId = result.headRevisionId;
      });
      return _put.apply(this, arguments);
    }

    function post(_x13, _x14) {
      return _post.apply(this, arguments);
    }

    function _post() {
      _post = _asyncToGenerator(function* (file, data) {
        const body = new FormData();
        const meta = {
          name: file,
          parents: ["appDataFolder"]
        };
        body.append("metadata", new Blob([JSON.stringify(meta)], {
          type: "application/json; charset=UTF-8"
        }));
        body.append("media", new Blob([data], {
          type: "text/plain"
        }));
        const result = yield request({
          method: "POST",
          path: "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,headRevisionId",
          body
        });
        fileMetaCache.set(result.name, result);
      });
      return _post.apply(this, arguments);
    }

    function delete_(_x15) {
      return _delete_.apply(this, arguments);
    }

    function _delete_() {
      _delete_ = _asyncToGenerator(function* (file) {
        const meta = fileMetaCache.get(file);

        if (!meta) {
          return;
        }

        try {
          yield request({
            method: "DELETE",
            path: "https://www.googleapis.com/drive/v3/files/".concat(meta.id)
          });
        } catch (err) {
          if (err.code === 404) {
            return;
          }

          throw err;
        }
      });
      return _delete_.apply(this, arguments);
    }
  }

  function dirname(path) {
    const dir = path.replace(/[/\\][^/\\]+\/?$/, "");
    if (dir === path) return ".";
    return dir;
  }

  const _excluded = ["path"];

  function arrayify(o) {
    return Array.isArray(o) ? o : [o];
  }

  function xmlToJSON(node) {
    // FIXME: xmldom doesn't support children
    const children = Array.prototype.filter.call(node.childNodes, i => i.nodeType === 1);

    if (!children.length) {
      return node.textContent;
    }

    const o = {};

    var _iterator = _createForOfIteratorHelper(children),
        _step;

    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        const c = _step.value;
        const cResult = xmlToJSON(c);

        if (!o[c.localName]) {
          o[c.localName] = cResult;
        } else if (!Array.isArray(o[c.localName])) {
          const list = [o[c.localName]];
          list.push(cResult);
          o[c.localName] = list;
        } else {
          o[c.localName].push(cResult);
        }
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }

    return o;
  }

  function createDrive({
    username,
    password,
    url,
    fetch = (typeof self !== "undefined" ? self : global).fetch,
    DOMParser = (typeof self !== "undefined" ? self : global).DOMParser
  }) {
    if (!url.endsWith("/")) {
      url += "/";
    }
    const request = createRequest({
      fetch,
      username,
      password
    });
    return {
      name: "webdav",
      get,
      put,
      post,
      delete: delete_,
      list // acquireLock,
      // releaseLock

    };

    function requestDAV(_x) {
      return _requestDAV.apply(this, arguments);
    }

    function _requestDAV() {
      _requestDAV = _asyncToGenerator(function* (_ref) {
        let path = _ref.path,
            args = _objectWithoutProperties(_ref, _excluded);

        const text = yield request(_objectSpread2({
          path: "".concat(url).concat(path)
        }, args));
        if (args.format || typeof text !== "string" || !text) return text;
        const parser = new DOMParser();
        const xml = parser.parseFromString(text, "application/xml");
        const result = xmlToJSON(xml);

        if (result.error) {
          throw new Error("Failed requesting DAV at ".concat(url).concat(path, ": ").concat(JSON.stringify(result.error)));
        }

        if (result.multistatus) {
          result.multistatus.response = arrayify(result.multistatus.response);

          var _iterator2 = _createForOfIteratorHelper(result.multistatus.response),
              _step2;

          try {
            for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
              const r = _step2.value;

              if (r.error) {
                throw new Error("Failed requesting DAV at ".concat(url).concat(path, ": ").concat(r.href, " ").concat(r.error));
              }
            }
          } catch (err) {
            _iterator2.e(err);
          } finally {
            _iterator2.f();
          }
        }

        return result;
      });
      return _requestDAV.apply(this, arguments);
    }

    function list(_x2) {
      return _list.apply(this, arguments);
    }

    function _list() {
      _list = _asyncToGenerator(function* (file) {
        if (!file.endsWith("/")) {
          file += "/";
        }

        const result = yield requestDAV({
          method: "PROPFIND",
          path: file,
          contentType: "application/xml",
          body: "<?xml version=\"1.0\" encoding=\"utf-8\" ?> \n        <propfind xmlns=\"DAV:\">\n          <allprop/>\n        </propfind>",
          headers: {
            "Depth": "1"
          }
        });
        const files = [];

        var _iterator3 = _createForOfIteratorHelper(arrayify(result.multistatus.response)),
            _step3;

        try {
          for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
            const entry = _step3.value;

            if (arrayify(entry.propstat).some(s => s.prop.resourcetype && s.prop.resourcetype.collection !== undefined)) {
              continue;
            }

            const base = "".concat(url).concat(file);
            const absUrl = new URL(entry.href, base).href;
            const name = absUrl.slice(base.length);
            files.push(name);
          }
        } catch (err) {
          _iterator3.e(err);
        } finally {
          _iterator3.f();
        }

        return files;
      });
      return _list.apply(this, arguments);
    }

    function get(_x3) {
      return _get.apply(this, arguments);
    }

    function _get() {
      _get = _asyncToGenerator(function* (file) {
        return yield requestDAV({
          method: "GET",
          path: file,
          format: "text"
        });
      });
      return _get.apply(this, arguments);
    }

    function put(_x4, _x5) {
      return _put.apply(this, arguments);
    }

    function _put() {
      _put = _asyncToGenerator(function* (file, data) {
        return yield withDir(dirname(file), () => requestDAV({
          method: "PUT",
          path: file,
          contentType: "application/octet-stream",
          body: data
        }));
      });
      return _put.apply(this, arguments);
    }

    function withDir(_x6, _x7) {
      return _withDir.apply(this, arguments);
    }

    function _withDir() {
      _withDir = _asyncToGenerator(function* (dir, cb) {
        try {
          return yield cb();
        } catch (err) {
          if (err.code !== 409 && err.code !== 404 || dir === ".") {
            throw err;
          }
        }

        yield withDir(dirname(dir), () => requestDAV({
          method: "MKCOL",
          path: dir
        }));
        return yield cb();
      });
      return _withDir.apply(this, arguments);
    }

    function post(_x8, _x9) {
      return _post.apply(this, arguments);
    }

    function _post() {
      _post = _asyncToGenerator(function* (file, data) {
        try {
          return yield withDir(dirname(file), () => requestDAV({
            method: "PUT",
            path: file,
            body: data,
            contentType: "octet-stream",
            headers: {
              // FIXME: seems webdav-server doesn't support etag, what about others?
              "If-None-Match": "*"
            }
          }));
        } catch (err) {
          if (err.code === 412) {
            err.code = "EEXIST";
          }

          throw err;
        }
      });
      return _post.apply(this, arguments);
    }

    function delete_(_x10) {
      return _delete_.apply(this, arguments);
    } // async function acquireLock(mins) {
    // const r = await requestDAV({
    // method: "LOCK",
    // path: "",
    // body: 
    // `<?xml version="1.0" encoding="utf-8" ?> 
    // <lockinfo xmlns='DAV:'> 
    // <lockscope><exclusive/></lockscope> 
    // <locktype><write/></locktype> 
    // </lockinfo> `,
    // headers: {
    // "Timeout": `Second-${mins * 60}`
    // },
    // raw: true
    // });
    // lockToken = r.headers.get("Lock-Token");
    // }
    // async function releaseLock() {
    // await requestDAV({
    // method: "UNLOCK",
    // path: "",
    // headers: {
    // "Lock-Token": lockToken
    // }
    // });
    // }


    function _delete_() {
      _delete_ = _asyncToGenerator(function* (file) {
        // FIXME: support deleting collections?
        // FIXME: handle errors?
        try {
          yield requestDAV({
            method: "DELETE",
            path: file
          });
        } catch (err) {
          if (err.code === 404) return;
          throw err;
        }
      });
      return _delete_.apply(this, arguments);
    }
  }

  var index = /*#__PURE__*/Object.freeze({
    __proto__: null,
    fsDrive: empty,
    github: createDrive$4,
    dropbox: createDrive$3,
    onedrive: createDrive$2,
    google: createDrive$1,
    webdav: createDrive
  });

  exports.dbToCloud = dbToCloud;
  exports.drive = index;

  Object.defineProperty(exports, '__esModule', { value: true });

  return exports;

}({}));