UNPKG

pauls-dat-api

Version:

Library of functions that make working with dat / hyperdrive easier.

243 lines (39 loc) 11.4 kB
'use strict';var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}();var recurseCopy = function () {var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark( function _callee5(archive, sourcePath, targetPath) {var _ref6, _ref7, sourceStat, targetStat, children, i;return regeneratorRuntime.wrap(function _callee5$(_context5) {while (1) {switch (_context5.prev = _context5.next) {case 0:_context5.next = 2;return ( Promise.all([ stat(archive, sourcePath), safeStat(archive, targetPath)]));case 2:_ref6 = _context5.sent;_ref7 = _slicedToArray(_ref6, 2);sourceStat = _ref7[0];targetStat = _ref7[1];if (! targetStat) {_context5.next = 13;break;}if (!( sourceStat.isFile() && !targetStat.isFile())) {_context5.next = 9;break;}throw ( new EntryAlreadyExistsError(`Cannot copy a file onto a folder (${targetPath})`));case 9:if (!( !sourceStat.isFile() && targetStat.isFile())) {_context5.next = 11;break;}throw ( new EntryAlreadyExistsError(`Cannot copy a folder onto a file (${targetPath})`));case 11:_context5.next = 16;break;case 13:if (! sourceStat.isDirectory()) {_context5.next = 16;break;}_context5.next = 16;return ( mkdir(archive, targetPath));case 16:if (! sourceStat.isFile()) {_context5.next = 20;break;}return _context5.abrupt('return', new Promise(function (resolve, reject) { pump( archive.createReadStream(sourcePath), archive.createWriteStream(targetPath), function (err) { if (err) reject(toBeakerError(err, 'createReadStream/createWriteStream'));else resolve(); }); }));case 20:if (! sourceStat.isDirectory()) {_context5.next = 33;break;}_context5.next = 23;return ( readdir(archive, sourcePath));case 23:children = _context5.sent; i = 0;case 25:if (!(i < children.length)) {_context5.next = 31;break;}_context5.next = 28;return ( recurseCopy( archive, path.join(sourcePath, children[i]), path.join(targetPath, children[i])));case 28:i++;_context5.next = 25;break;case 31:_context5.next = 34;break;case 33:throw ( new Error('Unexpectedly encountered an entry which is neither a file or directory at', path));case 34:case 'end':return _context5.stop();}}}, _callee5, this);}));return function recurseCopy(_x, _x2, _x3) {return _ref5.apply(this, arguments);};}();function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};}var path = require('path');var pump = require('pump');var _require = require('./common'),maybe = _require.maybe,toBeakerError = _require.toBeakerError,toValidEncoding = _require.toValidEncoding;var _require2 = require('./const'),VALID_PATH_REGEX = _require2.VALID_PATH_REGEX;var _require3 = require('beaker-error-constants'),InvalidEncodingError = _require3.InvalidEncodingError,InvalidPathError = _require3.InvalidPathError,ArchiveNotWritableError = _require3.ArchiveNotWritableError,EntryAlreadyExistsError = _require3.EntryAlreadyExistsError,ParentFolderDoesntExistError = _require3.ParentFolderDoesntExistError;var _require4 = require('./lookup'),stat = _require4.stat;var _require5 = require('./read'),readdir = _require5.readdir;var _require6 = require('./delete'),unlink = _require6.unlink,rmdir = _require6.rmdir;function writeFile(archive, name, data, opts, cb) {if (typeof opts === 'function') {cb = opts;opts = {};}return maybe(cb, _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {var existingEntry, parentName, parentEntry;return regeneratorRuntime.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:if (typeof opts === 'string') {opts = { encoding: opts };}opts = opts || {}; // ensure we have the archive's private key if (!(archive.key && !archive.writable)) {_context.next = 4;break;}throw new ArchiveNotWritableError();case 4:if (!(name.slice(-1) === '/')) {_context.next = 6;break;}throw new InvalidPathError('Files can not have a trailing slash');case 6:if (VALID_PATH_REGEX.test(name)) {_context.next = 8;break;}throw new InvalidPathError('Path contains invalid characters');case 8:_context.prev = 8;_context.next = 11;return stat(archive, name);case 11:existingEntry = _context.sent;_context.next = 16;break;case 14:_context.prev = 14;_context.t0 = _context['catch'](8);case 16:if (!(existingEntry && !existingEntry.isFile())) {_context.next = 18;break;}throw new EntryAlreadyExistsError('Cannot overwrite non-files');case 18: // copy ctime from the existing entry if (existingEntry) {opts.ctime = existingEntry.ctime;} // ensure that the parent directory exists parentName = path.dirname(name);if (!(parentName !== '/' && parentName !== '.')) {_context.next = 31;break;}_context.prev = 21;_context.next = 24;return stat(archive, parentName);case 24:parentEntry = _context.sent;_context.next = 29;break;case 27:_context.prev = 27;_context.t1 = _context['catch'](21);case 29:if (!(!parentEntry || !parentEntry.isDirectory())) {_context.next = 31;break;}throw new ParentFolderDoesntExistError();case 31: // guess the encoding by the data type if (!opts.encoding) {opts.encoding = typeof data === 'string' ? 'utf8' : 'binary';}opts.encoding = toValidEncoding(opts.encoding); // validate the encoding if (!(typeof data === 'string' && !opts.encoding)) {_context.next = 35;break;}throw new InvalidEncodingError();case 35:if (!(typeof data !== 'string' && opts.encoding)) {_context.next = 37;break;}throw new InvalidEncodingError();case 37:return _context.abrupt('return', new Promise(function (resolve, reject) {archive.writeFile(name, data, opts, function (err) {if (err) reject(toBeakerError(err, 'writeFile'));else resolve();});}));case 38:case 'end':return _context.stop();}}}, _callee, this, [[8, 14], [21, 27]]);})));}function mkdir(archive, name, cb) {return maybe(cb, _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {var existingEntry, parentName, parentEntry;return regeneratorRuntime.wrap(function _callee2$(_context2) {while (1) {switch (_context2.prev = _context2.next) {case 0:if (!(archive.key && !archive.writable)) {_context2.next = 2;break;}throw new ArchiveNotWritableError();case 2:if (VALID_PATH_REGEX.test(name)) {_context2.next = 4;break;}throw new InvalidPathError('Path contains invalid characters');case 4:_context2.prev = 4;_context2.next = 7;return stat(archive, name);case 7:existingEntry = _context2.sent;_context2.next = 12;break;case 10:_context2.prev = 10;_context2.t0 = _context2['catch'](4);case 12:if (!(name === '/' || existingEntry)) {_context2.next = 14;break;}throw new EntryAlreadyExistsError('Cannot overwrite files or folders');case 14: // ensure that the parent directory exists parentName = path.dirname(name);if (!(parentName !== '/' && parentName !== '.')) {_context2.next = 26;break;}_context2.prev = 16;_context2.next = 19;return stat(archive, parentName);case 19:parentEntry = _context2.sent;_context2.next = 24;break;case 22:_context2.prev = 22;_context2.t1 = _context2['catch'](16);case 24:if (!(!parentEntry || !parentEntry.isDirectory())) {_context2.next = 26;break;}throw new ParentFolderDoesntExistError();case 26:return _context2.abrupt('return', new Promise(function (resolve, reject) {archive.mkdir(name, function (err) {if (err) reject(toBeakerError(err, 'mkdir'));else resolve();});}));case 27:case 'end':return _context2.stop();}}}, _callee2, this, [[4, 10], [16, 22]]);})));}function copy(archive, oldName, newName, cb) {return maybe(cb, _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {var parentName, parentEntry;return regeneratorRuntime.wrap(function _callee3$(_context3) {while (1) {switch (_context3.prev = _context3.next) {case 0:if (!(archive.key && !archive.writable)) {_context3.next = 2;break;}throw new ArchiveNotWritableError();case 2:if (VALID_PATH_REGEX.test(newName)) {_context3.next = 4;break;}throw new InvalidPathError('Path contains invalid characters');case 4:if (!(newName === oldName || newName.startsWith(oldName + '/'))) {_context3.next = 6;break;}throw new InvalidPathError('Cannot move or copy a folder to a destination within itself');case 6: // ensure that the parent directory exists parentName = path.dirname(newName);if (!(parentName !== '/' && parentName !== '.')) {_context3.next = 18;break;}_context3.prev = 8;_context3.next = 11;return stat(archive, parentName);case 11:parentEntry = _context3.sent;_context3.next = 16;break;case 14:_context3.prev = 14;_context3.t0 = _context3['catch'](8);case 16:if (!(!parentEntry || !parentEntry.isDirectory())) {_context3.next = 18;break;}throw new ParentFolderDoesntExistError();case 18:_context3.next = 20;return recurseCopy(archive, oldName, newName);case 20:case 'end':return _context3.stop();}}}, _callee3, this, [[8, 14]]);})));}function rename(archive, oldName, newName, cb) {return maybe(cb, _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {var existingEntry, st;return regeneratorRuntime.wrap(function _callee4$(_context4) {while (1) {switch (_context4.prev = _context4.next) {case 0:_context4.prev = 0;_context4.next = 3;return stat(archive, newName);case 3:existingEntry = _context4.sent;_context4.next = 8;break;case 6:_context4.prev = 6;_context4.t0 = _context4['catch'](0);case 8:if (!(newName === '/' || existingEntry)) {_context4.next = 10;break;}throw new EntryAlreadyExistsError('Cannot overwrite files or folders');case 10:_context4.next = 12;return copy(archive, oldName, newName);case 12:_context4.next = 14;return stat(archive, oldName);case 14:st = _context4.sent;if (!st.isDirectory()) {_context4.next = 20;break;}_context4.next = 18;return rmdir(archive, oldName, { recursive: true });case 18:_context4.next = 22;break;case 20:_context4.next = 22;return unlink(archive, oldName);case 22:case 'end':return _context4.stop();}}}, _callee4, this, [[0, 6]]);})));}module.exports = { writeFile, mkdir, copy, rename // helpers // = };function safeStat(archive, path) {return stat(archive, path).catch(function (_) {return undefined;});}