@xen-orchestra/fs 0.17.0 → 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abstract.js +28 -8
- package/dist/abstract.js.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/local.js +4 -0
- package/dist/local.js.map +1 -1
- package/dist/s3.js +108 -49
- package/dist/s3.js.map +1 -1
- package/package.json +8 -8
- package/gitignore-test-s3.js +0 -34
package/dist/abstract.js
CHANGED
|
@@ -9,31 +9,31 @@ var _legacy = _interopRequireDefault(require("@xen-orchestra/async-map/legacy"))
|
|
|
9
9
|
|
|
10
10
|
var _getStream = _interopRequireDefault(require("get-stream"));
|
|
11
11
|
|
|
12
|
-
var _limitConcurrencyDecorator = _interopRequireDefault(require("limit-concurrency-decorator"));
|
|
13
|
-
|
|
14
12
|
var _path = _interopRequireWildcard(require("path"));
|
|
15
13
|
|
|
16
|
-
var _decoratorSynchronized = _interopRequireDefault(require("decorator-synchronized"));
|
|
17
|
-
|
|
18
14
|
var _coalesceCalls = require("@vates/coalesce-calls");
|
|
19
15
|
|
|
20
16
|
var _promiseToolbox = require("promise-toolbox");
|
|
21
17
|
|
|
18
|
+
var _limitConcurrencyDecorator = require("limit-concurrency-decorator");
|
|
19
|
+
|
|
22
20
|
var _xoRemoteParser = require("xo-remote-parser");
|
|
23
21
|
|
|
24
22
|
var _stream = require("stream");
|
|
25
23
|
|
|
26
24
|
var _crypto = require("crypto");
|
|
27
25
|
|
|
26
|
+
var _decoratorSynchronized = require("decorator-synchronized");
|
|
27
|
+
|
|
28
28
|
var _normalizePath = _interopRequireDefault(require("./_normalizePath"));
|
|
29
29
|
|
|
30
30
|
var _checksum = require("./checksum");
|
|
31
31
|
|
|
32
32
|
var _dec, _dec2, _class;
|
|
33
33
|
|
|
34
|
-
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var
|
|
34
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
35
35
|
|
|
36
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
36
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
37
37
|
|
|
38
38
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
39
39
|
|
|
@@ -94,7 +94,7 @@ class PrefixWrapper {
|
|
|
94
94
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.
|
|
97
|
+
let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.synchronized)(), _dec2 = (0, _decoratorSynchronized.synchronized)(), (_class = class RemoteHandlerAbstract {
|
|
98
98
|
constructor(remote, options = {}) {
|
|
99
99
|
var _options$maxParallelO;
|
|
100
100
|
|
|
@@ -115,8 +115,9 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.default)(), _dec2
|
|
|
115
115
|
highWaterMark: this._highWaterMark,
|
|
116
116
|
timeout: this._timeout = DEFAULT_TIMEOUT
|
|
117
117
|
} = options);
|
|
118
|
-
const sharedLimit = (0, _limitConcurrencyDecorator.
|
|
118
|
+
const sharedLimit = (0, _limitConcurrencyDecorator.limitConcurrency)((_options$maxParallelO = options.maxParallelOperations) !== null && _options$maxParallelO !== void 0 ? _options$maxParallelO : DEFAULT_MAX_PARALLEL_OPERATIONS);
|
|
119
119
|
this.closeFile = sharedLimit(this.closeFile);
|
|
120
|
+
this.copy = sharedLimit(this.copy);
|
|
120
121
|
this.getInfo = sharedLimit(this.getInfo);
|
|
121
122
|
this.getSize = sharedLimit(this.getSize);
|
|
122
123
|
this.list = sharedLimit(this.list);
|
|
@@ -366,6 +367,21 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.default)(), _dec2
|
|
|
366
367
|
return p;
|
|
367
368
|
}
|
|
368
369
|
|
|
370
|
+
async copy(oldPath, newPath, {
|
|
371
|
+
checksum = false
|
|
372
|
+
} = {}) {
|
|
373
|
+
oldPath = (0, _normalizePath.default)(oldPath);
|
|
374
|
+
newPath = (0, _normalizePath.default)(newPath);
|
|
375
|
+
|
|
376
|
+
let p = _promiseToolbox.timeout.call(this._copy(oldPath, newPath), this._timeout);
|
|
377
|
+
|
|
378
|
+
if (checksum) {
|
|
379
|
+
p = Promise.all([p, this._copy(checksumFile(oldPath), checksumFile(newPath))]);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return p;
|
|
383
|
+
}
|
|
384
|
+
|
|
369
385
|
async rmdir(dir) {
|
|
370
386
|
await _promiseToolbox.timeout.call(this._rmdir((0, _normalizePath.default)(dir)).catch(ignoreEnoent), this._timeout);
|
|
371
387
|
}
|
|
@@ -612,6 +628,10 @@ let RemoteHandlerAbstract = (_dec = (0, _decoratorSynchronized.default)(), _dec2
|
|
|
612
628
|
throw new Error('Not implemented');
|
|
613
629
|
}
|
|
614
630
|
|
|
631
|
+
async _copy(oldPath, newPath) {
|
|
632
|
+
throw new Error('Not implemented');
|
|
633
|
+
}
|
|
634
|
+
|
|
615
635
|
async _rmdir(dir) {
|
|
616
636
|
throw new Error('Not implemented');
|
|
617
637
|
}
|
package/dist/abstract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/abstract.js"],"names":["dirname","path","posix","checksumFile","file","computeRate","hrtime","size","seconds","DEFAULT_TIMEOUT","DEFAULT_MAX_PARALLEL_OPERATIONS","ignoreEnoent","error","code","noop","Function","prototype","PrefixWrapper","constructor","handler","prefix","_prefix","_handler","type","list","dir","opts","entries","_resolve","prependDir","n","length","forEach","entry","i","slice","rename","oldPath","newPath","RemoteHandlerAbstract","remote","options","url","_remote","Error","highWaterMark","_highWaterMark","timeout","_timeout","sharedLimit","maxParallelOperations","closeFile","getInfo","getSize","mkdir","openFile","outputFile","read","readFile","rmdir","truncate","unlink","write","writeFile","_forget","_sync","addPrefix","fd","__closeFile","createOutputStream","checksum","dirMode","streamP","call","_createOutputStream","flags","checksumStream","forwardError","emit","stream","on","pipe","checksumWritten","then","value","_outputFile","catch","createReadStream","ignoreMissingChecksum","_createReadStream","promise","undefined","end","start","Promise","all","ignoreErrors","_getSize","_readFile","String","trim","outputStream","input","validator","_outputStream","forget","_getInfo","filter","ignoreMissing","virtualDir","_list","lock","dispose","_lock","mode","__mkdir","mktree","_mktree","__openFile","data","buffer","position","_read","p","_rename","_rmdir","rmtree","_rmtree","sync","test","SIZE","testFileName","Date","now","randomBytes","step","writeStart","process","writeDuration","readStart","readDuration","equals","success","writeRate","readRate","message","_unlink","len","_truncate","_write","_writeFile","_closeFile","_mkdir","_openFile","_createWriteStream","resolve","tmpPath","output","pipeline","getStream","files","isPath","_writeFd","createPrefixWrapperMethods","pPw","pRha","defineProperty","getOwnPropertyDescriptor","hasOwnProperty","Object","getOwnPropertyNames","name","descriptor","arguments","apply"],"mappings":"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","sourcesContent":["import asyncMapSettled from '@xen-orchestra/async-map/legacy'\nimport getStream from 'get-stream'\nimport limit from 'limit-concurrency-decorator'\nimport path, { basename } from 'path'\nimport synchronized from 'decorator-synchronized'\nimport { coalesceCalls } from '@vates/coalesce-calls'\nimport { fromCallback, fromEvent, ignoreErrors, timeout } from 'promise-toolbox'\nimport { parse } from 'xo-remote-parser'\nimport { pipeline } from 'stream'\nimport { randomBytes } from 'crypto'\n\nimport normalizePath from './_normalizePath'\nimport { createChecksumStream, validChecksumOfReadStream } from './checksum'\n\nconst { dirname } = path.posix\n\nconst checksumFile = file => file + '.checksum'\nconst computeRate = (hrtime, size) => {\n const seconds = hrtime[0] + hrtime[1] / 1e9\n return size / seconds\n}\n\nconst DEFAULT_TIMEOUT = 6e5 // 10 min\nconst DEFAULT_MAX_PARALLEL_OPERATIONS = 10\n\nconst ignoreEnoent = error => {\n if (error == null || error.code !== 'ENOENT') {\n throw error\n }\n}\n\nconst noop = Function.prototype\n\nclass PrefixWrapper {\n constructor(handler, prefix) {\n this._prefix = prefix\n this._handler = handler\n }\n\n get type() {\n return this._handler.type\n }\n\n // necessary to remove the prefix from the path with `prependDir` option\n async list(dir, opts) {\n const entries = await this._handler.list(this._resolve(dir), opts)\n if (opts != null && opts.prependDir) {\n const n = this._prefix.length\n entries.forEach((entry, i, entries) => {\n entries[i] = entry.slice(n)\n })\n }\n return entries\n }\n\n rename(oldPath, newPath) {\n return this._handler.rename(this._resolve(oldPath), this._resolve(newPath))\n }\n\n _resolve(path) {\n return this._prefix + normalizePath(path)\n }\n}\n\nexport default class RemoteHandlerAbstract {\n constructor(remote, options = {}) {\n if (remote.url === 'test://') {\n this._remote = remote\n } else {\n this._remote = { ...remote, ...parse(remote.url) }\n if (this._remote.type !== this.type) {\n throw new Error('Incorrect remote type')\n }\n }\n ;({ highWaterMark: this._highWaterMark, timeout: this._timeout = DEFAULT_TIMEOUT } = options)\n\n const sharedLimit = limit(options.maxParallelOperations ?? DEFAULT_MAX_PARALLEL_OPERATIONS)\n this.closeFile = sharedLimit(this.closeFile)\n this.getInfo = sharedLimit(this.getInfo)\n this.getSize = sharedLimit(this.getSize)\n this.list = sharedLimit(this.list)\n this.mkdir = sharedLimit(this.mkdir)\n this.openFile = sharedLimit(this.openFile)\n this.outputFile = sharedLimit(this.outputFile)\n this.read = sharedLimit(this.read)\n this.readFile = sharedLimit(this.readFile)\n this.rename = sharedLimit(this.rename)\n this.rmdir = sharedLimit(this.rmdir)\n this.truncate = sharedLimit(this.truncate)\n this.unlink = sharedLimit(this.unlink)\n this.write = sharedLimit(this.write)\n this.writeFile = sharedLimit(this.writeFile)\n\n this._forget = coalesceCalls(this._forget)\n this._sync = coalesceCalls(this._sync)\n }\n\n // Public members\n\n get type() {\n throw new Error('Not implemented')\n }\n\n addPrefix(prefix) {\n prefix = normalizePath(prefix)\n return prefix === '/' ? this : new PrefixWrapper(this, prefix)\n }\n\n async closeFile(fd) {\n await this.__closeFile(fd)\n }\n\n // TODO: remove method\n async createOutputStream(file, { checksum = false, dirMode, ...options } = {}) {\n if (typeof file === 'string') {\n file = normalizePath(file)\n }\n const path = typeof file === 'string' ? file : file.path\n const streamP = timeout.call(\n this._createOutputStream(file, {\n dirMode,\n flags: 'wx',\n ...options,\n }),\n this._timeout\n )\n\n if (!checksum) {\n return streamP\n }\n\n const checksumStream = createChecksumStream()\n const forwardError = error => {\n checksumStream.emit('error', error)\n }\n\n const stream = await streamP\n stream.on('error', forwardError)\n checksumStream.pipe(stream)\n\n checksumStream.checksumWritten = checksumStream.checksum\n .then(value => this._outputFile(checksumFile(path), value, { flags: 'wx' }))\n .catch(forwardError)\n\n return checksumStream\n }\n\n createReadStream(file, { checksum = false, ignoreMissingChecksum = false, ...options } = {}) {\n if (typeof file === 'string') {\n file = normalizePath(file)\n }\n const path = typeof file === 'string' ? file : file.path\n const streamP = timeout\n .call(this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }), this._timeout)\n .then(stream => {\n // detect early errors\n let promise = fromEvent(stream, 'readable')\n\n // try to add the length prop if missing and not a range stream\n if (stream.length === undefined && options.end === undefined && options.start === undefined) {\n promise = Promise.all([\n promise,\n ignoreErrors.call(\n this._getSize(file).then(size => {\n stream.length = size\n })\n ),\n ])\n }\n\n return promise.then(() => stream)\n })\n\n if (!checksum) {\n return streamP\n }\n\n // avoid a unhandled rejection warning\n ignoreErrors.call(streamP)\n\n return this._readFile(checksumFile(path), { flags: 'r' }).then(\n checksum =>\n streamP.then(stream => {\n const { length } = stream\n stream = validChecksumOfReadStream(stream, String(checksum).trim())\n stream.length = length\n\n return stream\n }),\n error => {\n if (ignoreMissingChecksum && error && error.code === 'ENOENT') {\n return streamP\n }\n throw error\n }\n )\n }\n\n /**\n * write a stream to a file using a temporary file\n *\n * @param {string} path\n * @param {ReadableStream} input\n * @param {object} [options]\n * @param {boolean} [options.checksum]\n * @param {number} [options.dirMode]\n * @param {(this: RemoteHandlerAbstract, path: string) => Promise<undefined>} [options.validator] Function that will be called before the data is commited to the remote, if it fails, file should not exist\n */\n async outputStream(path, input, { checksum = true, dirMode, validator } = {}) {\n path = normalizePath(path)\n let checksumStream\n if (checksum) {\n checksumStream = createChecksumStream()\n pipeline(input, checksumStream, noop)\n input = checksumStream\n }\n await this._outputStream(path, input, {\n dirMode,\n validator,\n })\n if (checksum) {\n await this._outputFile(checksumFile(path), await checksumStream.checksum, { dirMode, flags: 'wx' })\n }\n }\n\n // Free the resources possibly dedicated to put the remote at work, when it\n // is no more needed\n //\n // FIXME: Some handlers are implemented based on system-wide mecanisms (such\n // as mount), forgetting them might breaking other processes using the same\n // remote.\n @synchronized()\n async forget() {\n await this._forget()\n }\n\n async getInfo() {\n return timeout.call(this._getInfo(), this._timeout)\n }\n\n async getSize(file) {\n return timeout.call(this._getSize(typeof file === 'string' ? normalizePath(file) : file), this._timeout)\n }\n\n async list(dir, { filter, ignoreMissing = false, prependDir = false } = {}) {\n try {\n const virtualDir = normalizePath(dir)\n dir = normalizePath(dir)\n\n let entries = await timeout.call(this._list(dir), this._timeout)\n if (filter !== undefined) {\n entries = entries.filter(filter)\n }\n\n if (prependDir) {\n entries.forEach((entry, i) => {\n entries[i] = virtualDir + '/' + entry\n })\n }\n\n return entries\n } catch (error) {\n if (ignoreMissing && error?.code === 'ENOENT') {\n return []\n }\n throw error\n }\n }\n\n async lock(path) {\n path = normalizePath(path)\n return { dispose: await this._lock(path) }\n }\n\n async mkdir(dir, { mode } = {}) {\n await this.__mkdir(normalizePath(dir), { mode })\n }\n\n async mktree(dir, { mode } = {}) {\n await this._mktree(normalizePath(dir), { mode })\n }\n\n openFile(path, flags) {\n return this.__openFile(path, flags)\n }\n\n async outputFile(file, data, { dirMode, flags = 'wx' } = {}) {\n await this._outputFile(normalizePath(file), data, { dirMode, flags })\n }\n\n async read(file, buffer, position) {\n return this._read(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async readFile(file, { flags = 'r' } = {}) {\n return this._readFile(normalizePath(file), { flags })\n }\n\n async rename(oldPath, newPath, { checksum = false } = {}) {\n oldPath = normalizePath(oldPath)\n newPath = normalizePath(newPath)\n\n let p = timeout.call(this._rename(oldPath, newPath), this._timeout)\n if (checksum) {\n p = Promise.all([p, this._rename(checksumFile(oldPath), checksumFile(newPath))])\n }\n return p\n }\n\n async rmdir(dir) {\n await timeout.call(this._rmdir(normalizePath(dir)).catch(ignoreEnoent), this._timeout)\n }\n\n async rmtree(dir) {\n await this._rmtree(normalizePath(dir))\n }\n\n // Asks the handler to sync the state of the effective remote with its'\n // metadata\n //\n // This method MUST ALWAYS be called before using the handler.\n @synchronized()\n async sync() {\n await this._sync()\n }\n\n async test() {\n const SIZE = 1024 * 1024 * 10\n const testFileName = normalizePath(`${Date.now()}.test`)\n const data = await fromCallback(randomBytes, SIZE)\n let step = 'write'\n try {\n const writeStart = process.hrtime()\n await this._outputFile(testFileName, data, { flags: 'wx' })\n const writeDuration = process.hrtime(writeStart)\n\n step = 'read'\n const readStart = process.hrtime()\n const read = await this._readFile(testFileName, { flags: 'r' })\n const readDuration = process.hrtime(readStart)\n\n if (!data.equals(read)) {\n throw new Error('output and input did not match')\n }\n return {\n success: true,\n writeRate: computeRate(writeDuration, SIZE),\n readRate: computeRate(readDuration, SIZE),\n }\n } catch (error) {\n return {\n success: false,\n step,\n file: testFileName,\n error: error.message || String(error),\n }\n } finally {\n ignoreErrors.call(this._unlink(testFileName))\n }\n }\n\n async truncate(file, len) {\n await this._truncate(file, len)\n }\n\n async unlink(file, { checksum = true } = {}) {\n file = normalizePath(file)\n\n if (checksum) {\n ignoreErrors.call(this._unlink(checksumFile(file)))\n }\n\n await this._unlink(file).catch(ignoreEnoent)\n }\n\n async write(file, buffer, position) {\n await this._write(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async writeFile(file, data, { flags = 'wx' } = {}) {\n await this._writeFile(normalizePath(file), data, { flags })\n }\n\n // Methods that can be called by private methods to avoid parallel limit on public methods\n\n async __closeFile(fd) {\n await timeout.call(this._closeFile(fd.fd), this._timeout)\n }\n\n async __mkdir(dir, { mode } = {}) {\n try {\n await this._mkdir(dir, { mode })\n } catch (error) {\n if (error == null || error.code !== 'EEXIST') {\n throw error\n }\n\n // this operation will throw if it's not already a directory\n await this._list(dir)\n }\n }\n\n async __openFile(path, flags) {\n path = normalizePath(path)\n\n return {\n fd: await timeout.call(this._openFile(path, flags), this._timeout),\n path,\n }\n }\n\n // Methods that can be implemented by inheriting classes\n\n async _closeFile(fd) {\n throw new Error('Not implemented')\n }\n\n async _createOutputStream(file, { dirMode, ...options } = {}) {\n try {\n return await this._createWriteStream(file, { ...options, highWaterMark: this._highWaterMark })\n } catch (error) {\n if (typeof file !== 'string' || error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._createOutputStream(file, options)\n }\n\n async _createReadStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // createWriteStream takes highWaterMark as option even if it's not documented.\n // Source: https://stackoverflow.com/questions/55026306/how-to-set-writeable-highwatermark\n async _createWriteStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // called to finalize the remote\n async _forget() {}\n\n async _getInfo() {\n return {}\n }\n\n async _lock(path) {\n return () => Promise.resolve()\n }\n\n async _getSize(file) {\n throw new Error('Not implemented')\n }\n\n async _list(dir) {\n throw new Error('Not implemented')\n }\n\n async _mkdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _mktree(dir, { mode } = {}) {\n try {\n return await this.__mkdir(dir, { mode })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(dir), { mode })\n return this._mktree(dir, { mode })\n }\n\n async _openFile(path, flags) {\n throw new Error('Not implemented')\n }\n\n async _outputFile(file, data, { dirMode, flags }) {\n try {\n return await this._writeFile(file, data, { flags })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._outputFile(file, data, { flags })\n }\n\n async _outputStream(path, input, { dirMode, validator }) {\n const tmpPath = `${dirname(path)}/.${basename(path)}`\n const output = await this.createOutputStream(tmpPath, {\n dirMode,\n })\n try {\n await fromCallback(pipeline, input, output)\n if (validator !== undefined) {\n await validator.call(this, tmpPath)\n }\n await this.rename(tmpPath, path)\n } catch (error) {\n await this.unlink(tmpPath)\n throw error\n }\n }\n\n _read(file, buffer, position) {\n throw new Error('Not implemented')\n }\n\n _readFile(file, options) {\n return this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }).then(getStream.buffer)\n }\n\n async _rename(oldPath, newPath) {\n throw new Error('Not implemented')\n }\n\n async _rmdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _rmtree(dir) {\n try {\n return await this._rmdir(dir)\n } catch (error) {\n if (error.code !== 'ENOTEMPTY') {\n throw error\n }\n }\n\n const files = await this._list(dir)\n await asyncMapSettled(files, file =>\n this._unlink(`${dir}/${file}`).catch(error => {\n if (error.code === 'EISDIR') {\n return this._rmtree(`${dir}/${file}`)\n }\n throw error\n })\n )\n return this._rmtree(dir)\n }\n\n // called to initialize the remote\n async _sync() {}\n\n async _unlink(file) {\n throw new Error('Not implemented')\n }\n\n async _write(file, buffer, position) {\n const isPath = typeof file === 'string'\n if (isPath) {\n file = await this.__openFile(file, 'r+')\n }\n try {\n return await this._writeFd(file, buffer, position)\n } finally {\n if (isPath) {\n await this.__closeFile(file)\n }\n }\n }\n\n async _writeFd(fd, buffer, position) {\n throw new Error('Not implemented')\n }\n\n async _writeFile(file, data, options) {\n throw new Error('Not implemented')\n }\n}\n\nfunction createPrefixWrapperMethods() {\n const pPw = PrefixWrapper.prototype\n const pRha = RemoteHandlerAbstract.prototype\n\n const {\n defineProperty,\n getOwnPropertyDescriptor,\n prototype: { hasOwnProperty },\n } = Object\n\n Object.getOwnPropertyNames(pRha).forEach(name => {\n let descriptor, value\n if (\n hasOwnProperty.call(pPw, name) ||\n name[0] === '_' ||\n typeof (value = (descriptor = getOwnPropertyDescriptor(pRha, name)).value) !== 'function'\n ) {\n return\n }\n\n descriptor.value = function () {\n let path\n if (arguments.length !== 0 && typeof (path = arguments[0]) === 'string') {\n arguments[0] = this._resolve(path)\n }\n return value.apply(this._handler, arguments)\n }\n\n defineProperty(pPw, name, descriptor)\n })\n}\ncreatePrefixWrapperMethods()\n"],"file":"abstract.js"}
|
|
1
|
+
{"version":3,"sources":["../src/abstract.js"],"names":["dirname","path","posix","checksumFile","file","computeRate","hrtime","size","seconds","DEFAULT_TIMEOUT","DEFAULT_MAX_PARALLEL_OPERATIONS","ignoreEnoent","error","code","noop","Function","prototype","PrefixWrapper","constructor","handler","prefix","_prefix","_handler","type","list","dir","opts","entries","_resolve","prependDir","n","length","forEach","entry","i","slice","rename","oldPath","newPath","RemoteHandlerAbstract","remote","options","url","_remote","Error","highWaterMark","_highWaterMark","timeout","_timeout","sharedLimit","maxParallelOperations","closeFile","copy","getInfo","getSize","mkdir","openFile","outputFile","read","readFile","rmdir","truncate","unlink","write","writeFile","_forget","_sync","addPrefix","fd","__closeFile","createOutputStream","checksum","dirMode","streamP","call","_createOutputStream","flags","checksumStream","forwardError","emit","stream","on","pipe","checksumWritten","then","value","_outputFile","catch","createReadStream","ignoreMissingChecksum","_createReadStream","promise","undefined","end","start","Promise","all","ignoreErrors","_getSize","_readFile","String","trim","outputStream","input","validator","_outputStream","forget","_getInfo","filter","ignoreMissing","virtualDir","_list","lock","dispose","_lock","mode","__mkdir","mktree","_mktree","__openFile","data","buffer","position","_read","p","_rename","_copy","_rmdir","rmtree","_rmtree","sync","test","SIZE","testFileName","Date","now","randomBytes","step","writeStart","process","writeDuration","readStart","readDuration","equals","success","writeRate","readRate","message","_unlink","len","_truncate","_write","_writeFile","_closeFile","_mkdir","_openFile","_createWriteStream","resolve","tmpPath","output","pipeline","getStream","files","isPath","_writeFd","createPrefixWrapperMethods","pPw","pRha","defineProperty","getOwnPropertyDescriptor","hasOwnProperty","Object","getOwnPropertyNames","name","descriptor","arguments","apply"],"mappings":"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","sourcesContent":["import asyncMapSettled from '@xen-orchestra/async-map/legacy'\nimport getStream from 'get-stream'\nimport path, { basename } from 'path'\nimport { coalesceCalls } from '@vates/coalesce-calls'\nimport { fromCallback, fromEvent, ignoreErrors, timeout } from 'promise-toolbox'\nimport { limitConcurrency } from 'limit-concurrency-decorator'\nimport { parse } from 'xo-remote-parser'\nimport { pipeline } from 'stream'\nimport { randomBytes } from 'crypto'\nimport { synchronized } from 'decorator-synchronized'\n\nimport normalizePath from './_normalizePath'\nimport { createChecksumStream, validChecksumOfReadStream } from './checksum'\n\nconst { dirname } = path.posix\n\nconst checksumFile = file => file + '.checksum'\nconst computeRate = (hrtime, size) => {\n const seconds = hrtime[0] + hrtime[1] / 1e9\n return size / seconds\n}\n\nconst DEFAULT_TIMEOUT = 6e5 // 10 min\nconst DEFAULT_MAX_PARALLEL_OPERATIONS = 10\n\nconst ignoreEnoent = error => {\n if (error == null || error.code !== 'ENOENT') {\n throw error\n }\n}\n\nconst noop = Function.prototype\n\nclass PrefixWrapper {\n constructor(handler, prefix) {\n this._prefix = prefix\n this._handler = handler\n }\n\n get type() {\n return this._handler.type\n }\n\n // necessary to remove the prefix from the path with `prependDir` option\n async list(dir, opts) {\n const entries = await this._handler.list(this._resolve(dir), opts)\n if (opts != null && opts.prependDir) {\n const n = this._prefix.length\n entries.forEach((entry, i, entries) => {\n entries[i] = entry.slice(n)\n })\n }\n return entries\n }\n\n rename(oldPath, newPath) {\n return this._handler.rename(this._resolve(oldPath), this._resolve(newPath))\n }\n\n _resolve(path) {\n return this._prefix + normalizePath(path)\n }\n}\n\nexport default class RemoteHandlerAbstract {\n constructor(remote, options = {}) {\n if (remote.url === 'test://') {\n this._remote = remote\n } else {\n this._remote = { ...remote, ...parse(remote.url) }\n if (this._remote.type !== this.type) {\n throw new Error('Incorrect remote type')\n }\n }\n ;({ highWaterMark: this._highWaterMark, timeout: this._timeout = DEFAULT_TIMEOUT } = options)\n\n const sharedLimit = limitConcurrency(options.maxParallelOperations ?? DEFAULT_MAX_PARALLEL_OPERATIONS)\n this.closeFile = sharedLimit(this.closeFile)\n this.copy = sharedLimit(this.copy)\n this.getInfo = sharedLimit(this.getInfo)\n this.getSize = sharedLimit(this.getSize)\n this.list = sharedLimit(this.list)\n this.mkdir = sharedLimit(this.mkdir)\n this.openFile = sharedLimit(this.openFile)\n this.outputFile = sharedLimit(this.outputFile)\n this.read = sharedLimit(this.read)\n this.readFile = sharedLimit(this.readFile)\n this.rename = sharedLimit(this.rename)\n this.rmdir = sharedLimit(this.rmdir)\n this.truncate = sharedLimit(this.truncate)\n this.unlink = sharedLimit(this.unlink)\n this.write = sharedLimit(this.write)\n this.writeFile = sharedLimit(this.writeFile)\n\n this._forget = coalesceCalls(this._forget)\n this._sync = coalesceCalls(this._sync)\n }\n\n // Public members\n\n get type() {\n throw new Error('Not implemented')\n }\n\n addPrefix(prefix) {\n prefix = normalizePath(prefix)\n return prefix === '/' ? this : new PrefixWrapper(this, prefix)\n }\n\n async closeFile(fd) {\n await this.__closeFile(fd)\n }\n\n // TODO: remove method\n async createOutputStream(file, { checksum = false, dirMode, ...options } = {}) {\n if (typeof file === 'string') {\n file = normalizePath(file)\n }\n const path = typeof file === 'string' ? file : file.path\n const streamP = timeout.call(\n this._createOutputStream(file, {\n dirMode,\n flags: 'wx',\n ...options,\n }),\n this._timeout\n )\n\n if (!checksum) {\n return streamP\n }\n\n const checksumStream = createChecksumStream()\n const forwardError = error => {\n checksumStream.emit('error', error)\n }\n\n const stream = await streamP\n stream.on('error', forwardError)\n checksumStream.pipe(stream)\n\n checksumStream.checksumWritten = checksumStream.checksum\n .then(value => this._outputFile(checksumFile(path), value, { flags: 'wx' }))\n .catch(forwardError)\n\n return checksumStream\n }\n\n createReadStream(file, { checksum = false, ignoreMissingChecksum = false, ...options } = {}) {\n if (typeof file === 'string') {\n file = normalizePath(file)\n }\n const path = typeof file === 'string' ? file : file.path\n const streamP = timeout\n .call(this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }), this._timeout)\n .then(stream => {\n // detect early errors\n let promise = fromEvent(stream, 'readable')\n\n // try to add the length prop if missing and not a range stream\n if (stream.length === undefined && options.end === undefined && options.start === undefined) {\n promise = Promise.all([\n promise,\n ignoreErrors.call(\n this._getSize(file).then(size => {\n stream.length = size\n })\n ),\n ])\n }\n\n return promise.then(() => stream)\n })\n\n if (!checksum) {\n return streamP\n }\n\n // avoid a unhandled rejection warning\n ignoreErrors.call(streamP)\n\n return this._readFile(checksumFile(path), { flags: 'r' }).then(\n checksum =>\n streamP.then(stream => {\n const { length } = stream\n stream = validChecksumOfReadStream(stream, String(checksum).trim())\n stream.length = length\n\n return stream\n }),\n error => {\n if (ignoreMissingChecksum && error && error.code === 'ENOENT') {\n return streamP\n }\n throw error\n }\n )\n }\n\n /**\n * write a stream to a file using a temporary file\n *\n * @param {string} path\n * @param {ReadableStream} input\n * @param {object} [options]\n * @param {boolean} [options.checksum]\n * @param {number} [options.dirMode]\n * @param {(this: RemoteHandlerAbstract, path: string) => Promise<undefined>} [options.validator] Function that will be called before the data is commited to the remote, if it fails, file should not exist\n */\n async outputStream(path, input, { checksum = true, dirMode, validator } = {}) {\n path = normalizePath(path)\n let checksumStream\n if (checksum) {\n checksumStream = createChecksumStream()\n pipeline(input, checksumStream, noop)\n input = checksumStream\n }\n await this._outputStream(path, input, {\n dirMode,\n validator,\n })\n if (checksum) {\n await this._outputFile(checksumFile(path), await checksumStream.checksum, { dirMode, flags: 'wx' })\n }\n }\n\n // Free the resources possibly dedicated to put the remote at work, when it\n // is no more needed\n //\n // FIXME: Some handlers are implemented based on system-wide mecanisms (such\n // as mount), forgetting them might breaking other processes using the same\n // remote.\n @synchronized()\n async forget() {\n await this._forget()\n }\n\n async getInfo() {\n return timeout.call(this._getInfo(), this._timeout)\n }\n\n async getSize(file) {\n return timeout.call(this._getSize(typeof file === 'string' ? normalizePath(file) : file), this._timeout)\n }\n\n async list(dir, { filter, ignoreMissing = false, prependDir = false } = {}) {\n try {\n const virtualDir = normalizePath(dir)\n dir = normalizePath(dir)\n\n let entries = await timeout.call(this._list(dir), this._timeout)\n if (filter !== undefined) {\n entries = entries.filter(filter)\n }\n\n if (prependDir) {\n entries.forEach((entry, i) => {\n entries[i] = virtualDir + '/' + entry\n })\n }\n\n return entries\n } catch (error) {\n if (ignoreMissing && error?.code === 'ENOENT') {\n return []\n }\n throw error\n }\n }\n\n async lock(path) {\n path = normalizePath(path)\n return { dispose: await this._lock(path) }\n }\n\n async mkdir(dir, { mode } = {}) {\n await this.__mkdir(normalizePath(dir), { mode })\n }\n\n async mktree(dir, { mode } = {}) {\n await this._mktree(normalizePath(dir), { mode })\n }\n\n openFile(path, flags) {\n return this.__openFile(path, flags)\n }\n\n async outputFile(file, data, { dirMode, flags = 'wx' } = {}) {\n await this._outputFile(normalizePath(file), data, { dirMode, flags })\n }\n\n async read(file, buffer, position) {\n return this._read(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async readFile(file, { flags = 'r' } = {}) {\n return this._readFile(normalizePath(file), { flags })\n }\n\n async rename(oldPath, newPath, { checksum = false } = {}) {\n oldPath = normalizePath(oldPath)\n newPath = normalizePath(newPath)\n\n let p = timeout.call(this._rename(oldPath, newPath), this._timeout)\n if (checksum) {\n p = Promise.all([p, this._rename(checksumFile(oldPath), checksumFile(newPath))])\n }\n return p\n }\n\n async copy(oldPath, newPath, { checksum = false } = {}) {\n oldPath = normalizePath(oldPath)\n newPath = normalizePath(newPath)\n\n let p = timeout.call(this._copy(oldPath, newPath), this._timeout)\n if (checksum) {\n p = Promise.all([p, this._copy(checksumFile(oldPath), checksumFile(newPath))])\n }\n return p\n }\n\n async rmdir(dir) {\n await timeout.call(this._rmdir(normalizePath(dir)).catch(ignoreEnoent), this._timeout)\n }\n\n async rmtree(dir) {\n await this._rmtree(normalizePath(dir))\n }\n\n // Asks the handler to sync the state of the effective remote with its'\n // metadata\n //\n // This method MUST ALWAYS be called before using the handler.\n @synchronized()\n async sync() {\n await this._sync()\n }\n\n async test() {\n const SIZE = 1024 * 1024 * 10\n const testFileName = normalizePath(`${Date.now()}.test`)\n const data = await fromCallback(randomBytes, SIZE)\n let step = 'write'\n try {\n const writeStart = process.hrtime()\n await this._outputFile(testFileName, data, { flags: 'wx' })\n const writeDuration = process.hrtime(writeStart)\n\n step = 'read'\n const readStart = process.hrtime()\n const read = await this._readFile(testFileName, { flags: 'r' })\n const readDuration = process.hrtime(readStart)\n\n if (!data.equals(read)) {\n throw new Error('output and input did not match')\n }\n return {\n success: true,\n writeRate: computeRate(writeDuration, SIZE),\n readRate: computeRate(readDuration, SIZE),\n }\n } catch (error) {\n return {\n success: false,\n step,\n file: testFileName,\n error: error.message || String(error),\n }\n } finally {\n ignoreErrors.call(this._unlink(testFileName))\n }\n }\n\n async truncate(file, len) {\n await this._truncate(file, len)\n }\n\n async unlink(file, { checksum = true } = {}) {\n file = normalizePath(file)\n\n if (checksum) {\n ignoreErrors.call(this._unlink(checksumFile(file)))\n }\n\n await this._unlink(file).catch(ignoreEnoent)\n }\n\n async write(file, buffer, position) {\n await this._write(typeof file === 'string' ? normalizePath(file) : file, buffer, position)\n }\n\n async writeFile(file, data, { flags = 'wx' } = {}) {\n await this._writeFile(normalizePath(file), data, { flags })\n }\n\n // Methods that can be called by private methods to avoid parallel limit on public methods\n\n async __closeFile(fd) {\n await timeout.call(this._closeFile(fd.fd), this._timeout)\n }\n\n async __mkdir(dir, { mode } = {}) {\n try {\n await this._mkdir(dir, { mode })\n } catch (error) {\n if (error == null || error.code !== 'EEXIST') {\n throw error\n }\n\n // this operation will throw if it's not already a directory\n await this._list(dir)\n }\n }\n\n async __openFile(path, flags) {\n path = normalizePath(path)\n\n return {\n fd: await timeout.call(this._openFile(path, flags), this._timeout),\n path,\n }\n }\n\n // Methods that can be implemented by inheriting classes\n\n async _closeFile(fd) {\n throw new Error('Not implemented')\n }\n\n async _createOutputStream(file, { dirMode, ...options } = {}) {\n try {\n return await this._createWriteStream(file, { ...options, highWaterMark: this._highWaterMark })\n } catch (error) {\n if (typeof file !== 'string' || error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._createOutputStream(file, options)\n }\n\n async _createReadStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // createWriteStream takes highWaterMark as option even if it's not documented.\n // Source: https://stackoverflow.com/questions/55026306/how-to-set-writeable-highwatermark\n async _createWriteStream(file, options) {\n throw new Error('Not implemented')\n }\n\n // called to finalize the remote\n async _forget() {}\n\n async _getInfo() {\n return {}\n }\n\n async _lock(path) {\n return () => Promise.resolve()\n }\n\n async _getSize(file) {\n throw new Error('Not implemented')\n }\n\n async _list(dir) {\n throw new Error('Not implemented')\n }\n\n async _mkdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _mktree(dir, { mode } = {}) {\n try {\n return await this.__mkdir(dir, { mode })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(dir), { mode })\n return this._mktree(dir, { mode })\n }\n\n async _openFile(path, flags) {\n throw new Error('Not implemented')\n }\n\n async _outputFile(file, data, { dirMode, flags }) {\n try {\n return await this._writeFile(file, data, { flags })\n } catch (error) {\n if (error.code !== 'ENOENT') {\n throw error\n }\n }\n\n await this._mktree(dirname(file), { mode: dirMode })\n return this._outputFile(file, data, { flags })\n }\n\n async _outputStream(path, input, { dirMode, validator }) {\n const tmpPath = `${dirname(path)}/.${basename(path)}`\n const output = await this.createOutputStream(tmpPath, {\n dirMode,\n })\n try {\n await fromCallback(pipeline, input, output)\n if (validator !== undefined) {\n await validator.call(this, tmpPath)\n }\n await this.rename(tmpPath, path)\n } catch (error) {\n await this.unlink(tmpPath)\n throw error\n }\n }\n\n _read(file, buffer, position) {\n throw new Error('Not implemented')\n }\n\n _readFile(file, options) {\n return this._createReadStream(file, { ...options, highWaterMark: this._highWaterMark }).then(getStream.buffer)\n }\n\n async _rename(oldPath, newPath) {\n throw new Error('Not implemented')\n }\n async _copy(oldPath, newPath) {\n throw new Error('Not implemented')\n }\n\n async _rmdir(dir) {\n throw new Error('Not implemented')\n }\n\n async _rmtree(dir) {\n try {\n return await this._rmdir(dir)\n } catch (error) {\n if (error.code !== 'ENOTEMPTY') {\n throw error\n }\n }\n\n const files = await this._list(dir)\n await asyncMapSettled(files, file =>\n this._unlink(`${dir}/${file}`).catch(error => {\n if (error.code === 'EISDIR') {\n return this._rmtree(`${dir}/${file}`)\n }\n throw error\n })\n )\n return this._rmtree(dir)\n }\n\n // called to initialize the remote\n async _sync() {}\n\n async _unlink(file) {\n throw new Error('Not implemented')\n }\n\n async _write(file, buffer, position) {\n const isPath = typeof file === 'string'\n if (isPath) {\n file = await this.__openFile(file, 'r+')\n }\n try {\n return await this._writeFd(file, buffer, position)\n } finally {\n if (isPath) {\n await this.__closeFile(file)\n }\n }\n }\n\n async _writeFd(fd, buffer, position) {\n throw new Error('Not implemented')\n }\n\n async _writeFile(file, data, options) {\n throw new Error('Not implemented')\n }\n}\n\nfunction createPrefixWrapperMethods() {\n const pPw = PrefixWrapper.prototype\n const pRha = RemoteHandlerAbstract.prototype\n\n const {\n defineProperty,\n getOwnPropertyDescriptor,\n prototype: { hasOwnProperty },\n } = Object\n\n Object.getOwnPropertyNames(pRha).forEach(name => {\n let descriptor, value\n if (\n hasOwnProperty.call(pPw, name) ||\n name[0] === '_' ||\n typeof (value = (descriptor = getOwnPropertyDescriptor(pRha, name)).value) !== 'function'\n ) {\n return\n }\n\n descriptor.value = function () {\n let path\n if (arguments.length !== 0 && typeof (path = arguments[0]) === 'string') {\n arguments[0] = this._resolve(path)\n }\n return value.apply(this._handler, arguments)\n }\n\n defineProperty(pPw, name, descriptor)\n })\n}\ncreatePrefixWrapperMethods()\n"],"file":"abstract.js"}
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getHandler = void 0;
|
|
6
|
+
exports.getSyncedHandler = exports.getHandler = void 0;
|
|
7
7
|
|
|
8
8
|
var _execa = _interopRequireDefault(require("execa"));
|
|
9
9
|
|
|
@@ -46,4 +46,15 @@ const getHandler = (remote, ...rest) => {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
exports.getHandler = getHandler;
|
|
49
|
+
|
|
50
|
+
const getSyncedHandler = async (...opts) => {
|
|
51
|
+
const handler = getHandler(...opts);
|
|
52
|
+
await handler.sync();
|
|
53
|
+
return {
|
|
54
|
+
dispose: () => handler.forget(),
|
|
55
|
+
value: handler
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
exports.getSyncedHandler = getSyncedHandler;
|
|
49
60
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["HANDLERS","file","RemoteHandlerLocal","nfs","RemoteHandlerNfs","s3","RemoteHandlerS3","execa","sync","smb","RemoteHandlerSmbMount","_","RemoteHandlerSmb","getHandler","remote","rest","Handler","url","type","Error"],"mappings":";;;;;;;AAAA;;AACA;;AAEA;;AACA;;AACA;;AACA;;AACA;;;;AAEA,MAAMA,QAAQ,GAAG;AACfC,EAAAA,IAAI,EAAEC,cADS;AAEfC,EAAAA,GAAG,EAAEC,YAFU;AAGfC,EAAAA,EAAE,EAAEC;AAHW,CAAjB;;AAMA,IAAI;AACFC,iBAAMC,IAAN,CAAW,YAAX,EAAyB,CAAC,IAAD,CAAzB;;AACAR,EAAAA,QAAQ,CAACS,GAAT,GAAeC,iBAAf;AACD,CAHD,CAGE,OAAOC,CAAP,EAAU;AACVX,EAAAA,QAAQ,CAACS,GAAT,GAAeG,YAAf;AACD;;AAEM,MAAMC,UAAU,GAAG,CAACC,MAAD,EAAS,GAAGC,IAAZ,KAAqB;AAC7C,QAAMC,OAAO,GAAGhB,QAAQ,CAAC,2BAAMc,MAAM,CAACG,GAAb,EAAkBC,IAAnB,CAAxB;;AACA,MAAI,CAACF,OAAL,EAAc;AACZ,UAAM,IAAIG,KAAJ,CAAU,uBAAV,CAAN;AACD;;AACD,SAAO,IAAIH,OAAJ,CAAYF,MAAZ,EAAoB,GAAGC,IAAvB,CAAP;AACD,CANM","sourcesContent":["import execa from 'execa'\nimport { parse } from 'xo-remote-parser'\n\nimport RemoteHandlerLocal from './local'\nimport RemoteHandlerNfs from './nfs'\nimport RemoteHandlerS3 from './s3'\nimport RemoteHandlerSmb from './smb'\nimport RemoteHandlerSmbMount from './smb-mount'\n\nconst HANDLERS = {\n file: RemoteHandlerLocal,\n nfs: RemoteHandlerNfs,\n s3: RemoteHandlerS3,\n}\n\ntry {\n execa.sync('mount.cifs', ['-V'])\n HANDLERS.smb = RemoteHandlerSmbMount\n} catch (_) {\n HANDLERS.smb = RemoteHandlerSmb\n}\n\nexport const getHandler = (remote, ...rest) => {\n const Handler = HANDLERS[parse(remote.url).type]\n if (!Handler) {\n throw new Error('Unhandled remote type')\n }\n return new Handler(remote, ...rest)\n}\n"],"file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["HANDLERS","file","RemoteHandlerLocal","nfs","RemoteHandlerNfs","s3","RemoteHandlerS3","execa","sync","smb","RemoteHandlerSmbMount","_","RemoteHandlerSmb","getHandler","remote","rest","Handler","url","type","Error","getSyncedHandler","opts","handler","dispose","forget","value"],"mappings":";;;;;;;AAAA;;AACA;;AAEA;;AACA;;AACA;;AACA;;AACA;;;;AAEA,MAAMA,QAAQ,GAAG;AACfC,EAAAA,IAAI,EAAEC,cADS;AAEfC,EAAAA,GAAG,EAAEC,YAFU;AAGfC,EAAAA,EAAE,EAAEC;AAHW,CAAjB;;AAMA,IAAI;AACFC,iBAAMC,IAAN,CAAW,YAAX,EAAyB,CAAC,IAAD,CAAzB;;AACAR,EAAAA,QAAQ,CAACS,GAAT,GAAeC,iBAAf;AACD,CAHD,CAGE,OAAOC,CAAP,EAAU;AACVX,EAAAA,QAAQ,CAACS,GAAT,GAAeG,YAAf;AACD;;AAEM,MAAMC,UAAU,GAAG,CAACC,MAAD,EAAS,GAAGC,IAAZ,KAAqB;AAC7C,QAAMC,OAAO,GAAGhB,QAAQ,CAAC,2BAAMc,MAAM,CAACG,GAAb,EAAkBC,IAAnB,CAAxB;;AACA,MAAI,CAACF,OAAL,EAAc;AACZ,UAAM,IAAIG,KAAJ,CAAU,uBAAV,CAAN;AACD;;AACD,SAAO,IAAIH,OAAJ,CAAYF,MAAZ,EAAoB,GAAGC,IAAvB,CAAP;AACD,CANM;;;;AAQA,MAAMK,gBAAgB,GAAG,OAAO,GAAGC,IAAV,KAAmB;AACjD,QAAMC,OAAO,GAAGT,UAAU,CAAC,GAAGQ,IAAJ,CAA1B;AACA,QAAMC,OAAO,CAACd,IAAR,EAAN;AACA,SAAO;AACLe,IAAAA,OAAO,EAAE,MAAMD,OAAO,CAACE,MAAR,EADV;AAELC,IAAAA,KAAK,EAAEH;AAFF,GAAP;AAID,CAPM","sourcesContent":["import execa from 'execa'\nimport { parse } from 'xo-remote-parser'\n\nimport RemoteHandlerLocal from './local'\nimport RemoteHandlerNfs from './nfs'\nimport RemoteHandlerS3 from './s3'\nimport RemoteHandlerSmb from './smb'\nimport RemoteHandlerSmbMount from './smb-mount'\n\nconst HANDLERS = {\n file: RemoteHandlerLocal,\n nfs: RemoteHandlerNfs,\n s3: RemoteHandlerS3,\n}\n\ntry {\n execa.sync('mount.cifs', ['-V'])\n HANDLERS.smb = RemoteHandlerSmbMount\n} catch (_) {\n HANDLERS.smb = RemoteHandlerSmb\n}\n\nexport const getHandler = (remote, ...rest) => {\n const Handler = HANDLERS[parse(remote.url).type]\n if (!Handler) {\n throw new Error('Unhandled remote type')\n }\n return new Handler(remote, ...rest)\n}\n\nexport const getSyncedHandler = async (...opts) => {\n const handler = getHandler(...opts)\n await handler.sync()\n return {\n dispose: () => handler.forget(),\n value: handler,\n }\n}\n"],"file":"index.js"}
|
package/dist/local.js
CHANGED
|
@@ -46,6 +46,10 @@ class LocalHandler extends _abstract.default {
|
|
|
46
46
|
return _fsExtra.default.close(fd);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
async _copy(oldPath, newPath) {
|
|
50
|
+
return _fsExtra.default.copy(this._getFilePath(oldPath), this._getFilePath(newPath));
|
|
51
|
+
}
|
|
52
|
+
|
|
49
53
|
async _createReadStream(file, options) {
|
|
50
54
|
if (typeof file === 'string') {
|
|
51
55
|
const stream = _fsExtra.default.createReadStream(this._getFilePath(file), options);
|
package/dist/local.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/local.js"],"names":["LocalHandler","RemoteHandlerAbstract","constructor","remote","opts","_retriesOnEagain","delay","retries","retriesOnEagain","when","code","type","_getRealPath","_remote","path","_getFilePath","file","_closeFile","fd","fs","close","_createReadStream","options","stream","createReadStream","autoClose","_createWriteStream","createWriteStream","_getInfo","info","df","Object","keys","forEach","key","Number","isNaN","_getSize","stats","stat","size","_list","dir","readdir","_lock","lockfile","lock","_mkdir","mode","mkdir","_openFile","flags","open","_read","buffer","position","needsClose","read","length","undefined","_readFile","filePath","readFile","_rename","
|
|
1
|
+
{"version":3,"sources":["../src/local.js"],"names":["LocalHandler","RemoteHandlerAbstract","constructor","remote","opts","_retriesOnEagain","delay","retries","retriesOnEagain","when","code","type","_getRealPath","_remote","path","_getFilePath","file","_closeFile","fd","fs","close","_copy","oldPath","newPath","copy","_createReadStream","options","stream","createReadStream","autoClose","_createWriteStream","createWriteStream","_getInfo","info","df","Object","keys","forEach","key","Number","isNaN","_getSize","stats","stat","size","_list","dir","readdir","_lock","lockfile","lock","_mkdir","mode","mkdir","_openFile","flags","open","_read","buffer","position","needsClose","read","length","undefined","_readFile","filePath","readFile","_rename","rename","_rmdir","rmdir","_sync","ensureDir","access","R_OK","W_OK","_truncate","len","truncate","_unlink","unlink","_writeFd","write","_writeFile","data","writeFile","flag"],"mappings":"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","sourcesContent":["import df from '@sindresorhus/df'\nimport fs from 'fs-extra'\nimport lockfile from 'proper-lockfile'\nimport { fromEvent, retry } from 'promise-toolbox'\n\nimport RemoteHandlerAbstract from './abstract'\n\nexport default class LocalHandler extends RemoteHandlerAbstract {\n constructor(remote, opts = {}) {\n super(remote)\n this._retriesOnEagain = {\n delay: 1e3,\n retries: 9,\n ...opts.retriesOnEagain,\n when: {\n code: 'EAGAIN',\n },\n }\n }\n get type() {\n return 'file'\n }\n\n _getRealPath() {\n return this._remote.path\n }\n\n _getFilePath(file) {\n return this._getRealPath() + file\n }\n\n async _closeFile(fd) {\n return fs.close(fd)\n }\n\n async _copy(oldPath, newPath) {\n return fs.copy(this._getFilePath(oldPath), this._getFilePath(newPath))\n }\n\n async _createReadStream(file, options) {\n if (typeof file === 'string') {\n const stream = fs.createReadStream(this._getFilePath(file), options)\n await fromEvent(stream, 'open')\n return stream\n }\n return fs.createReadStream('', {\n autoClose: false,\n ...options,\n fd: file.fd,\n })\n }\n\n async _createWriteStream(file, options) {\n if (typeof file === 'string') {\n const stream = fs.createWriteStream(this._getFilePath(file), options)\n await fromEvent(stream, 'open')\n return stream\n }\n return fs.createWriteStream('', {\n autoClose: false,\n ...options,\n fd: file.fd,\n })\n }\n\n async _getInfo() {\n // df.file() resolves with an object with the following properties:\n // filesystem, type, size, used, available, capacity and mountpoint.\n // size, used, available and capacity may be `NaN` so we remove any `NaN`\n // value from the object.\n const info = await df.file(this._getFilePath('/'))\n Object.keys(info).forEach(key => {\n if (Number.isNaN(info[key])) {\n delete info[key]\n }\n })\n\n return info\n }\n\n async _getSize(file) {\n const stats = await fs.stat(this._getFilePath(typeof file === 'string' ? file : file.path))\n return stats.size\n }\n\n async _list(dir) {\n return fs.readdir(this._getFilePath(dir))\n }\n\n _lock(path) {\n return lockfile.lock(this._getFilePath(path))\n }\n\n _mkdir(dir, { mode }) {\n return fs.mkdir(this._getFilePath(dir), { mode })\n }\n\n async _openFile(path, flags) {\n return fs.open(this._getFilePath(path), flags)\n }\n\n async _read(file, buffer, position) {\n const needsClose = typeof file === 'string'\n file = needsClose ? await fs.open(this._getFilePath(file), 'r') : file.fd\n try {\n return await fs.read(file, buffer, 0, buffer.length, position === undefined ? null : position)\n } finally {\n if (needsClose) {\n await fs.close(file)\n }\n }\n }\n\n async _readFile(file, options) {\n const filePath = this._getFilePath(file)\n return await retry(() => fs.readFile(filePath, options), this._retriesOnEagain)\n }\n\n async _rename(oldPath, newPath) {\n return fs.rename(this._getFilePath(oldPath), this._getFilePath(newPath))\n }\n\n async _rmdir(dir) {\n return fs.rmdir(this._getFilePath(dir))\n }\n\n async _sync() {\n const path = this._getRealPath('/')\n await fs.ensureDir(path)\n await fs.access(path, fs.R_OK | fs.W_OK)\n }\n\n _truncate(file, len) {\n return fs.truncate(this._getFilePath(file), len)\n }\n\n async _unlink(file) {\n const filePath = this._getFilePath(file)\n return await retry(() => fs.unlink(filePath), this._retriesOnEagain)\n }\n\n _writeFd(file, buffer, position) {\n return fs.write(file.fd, buffer, 0, buffer.length, position)\n }\n\n _writeFile(file, data, { flags }) {\n return fs.writeFile(this._getFilePath(file), data, { flag: flags })\n }\n}\n"],"file":"local.js"}
|
package/dist/s3.js
CHANGED
|
@@ -11,6 +11,8 @@ var _assert = _interopRequireDefault(require("assert"));
|
|
|
11
11
|
|
|
12
12
|
var _http = _interopRequireDefault(require("http"));
|
|
13
13
|
|
|
14
|
+
var _https = _interopRequireDefault(require("https"));
|
|
15
|
+
|
|
14
16
|
var _xoRemoteParser = require("xo-remote-parser");
|
|
15
17
|
|
|
16
18
|
var _abstract = _interopRequireDefault(require("./abstract"));
|
|
@@ -27,6 +29,7 @@ class S3Handler extends _abstract.default {
|
|
|
27
29
|
constructor(remote, _opts) {
|
|
28
30
|
super(remote);
|
|
29
31
|
const {
|
|
32
|
+
allowUnauthorized,
|
|
30
33
|
host,
|
|
31
34
|
path,
|
|
32
35
|
username,
|
|
@@ -47,8 +50,15 @@ class S3Handler extends _abstract.default {
|
|
|
47
50
|
};
|
|
48
51
|
|
|
49
52
|
if (protocol === 'http') {
|
|
50
|
-
params.httpOptions.agent = new _http.default.Agent(
|
|
53
|
+
params.httpOptions.agent = new _http.default.Agent({
|
|
54
|
+
keepAlive: true
|
|
55
|
+
});
|
|
51
56
|
params.sslEnabled = false;
|
|
57
|
+
} else if (protocol === 'https') {
|
|
58
|
+
params.httpOptions.agent = new _https.default.Agent({
|
|
59
|
+
rejectUnauthorized: !allowUnauthorized,
|
|
60
|
+
keepAlive: true
|
|
61
|
+
});
|
|
52
62
|
}
|
|
53
63
|
|
|
54
64
|
if (region !== undefined) {
|
|
@@ -72,6 +82,43 @@ class S3Handler extends _abstract.default {
|
|
|
72
82
|
};
|
|
73
83
|
}
|
|
74
84
|
|
|
85
|
+
async _copy(oldPath, newPath) {
|
|
86
|
+
const size = await this._getSize(oldPath);
|
|
87
|
+
const multipartParams = await this._s3.createMultipartUpload({ ...this._createParams(newPath)
|
|
88
|
+
});
|
|
89
|
+
const param2 = { ...multipartParams,
|
|
90
|
+
CopySource: `/${this._bucket}/${this._dir}${oldPath}`
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const parts = [];
|
|
95
|
+
let start = 0;
|
|
96
|
+
|
|
97
|
+
while (start < size) {
|
|
98
|
+
const range = `bytes=${start}-${Math.min(start + MAX_PART_SIZE, size) - 1}`;
|
|
99
|
+
const partParams = { ...param2,
|
|
100
|
+
PartNumber: parts.length + 1,
|
|
101
|
+
CopySourceRange: range
|
|
102
|
+
};
|
|
103
|
+
const upload = await this._s3.uploadPartCopy(partParams);
|
|
104
|
+
parts.push({
|
|
105
|
+
ETag: upload.CopyPartResult.ETag,
|
|
106
|
+
PartNumber: partParams.PartNumber
|
|
107
|
+
});
|
|
108
|
+
start += MAX_PART_SIZE;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await this._s3.completeMultipartUpload({ ...multipartParams,
|
|
112
|
+
MultipartUpload: {
|
|
113
|
+
Parts: parts
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
} catch (e) {
|
|
117
|
+
await this._s3.abortMultipartUpload(multipartParams);
|
|
118
|
+
throw e;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
75
122
|
async _isNotEmptyDir(path) {
|
|
76
123
|
const result = await this._s3.listObjectsV2({
|
|
77
124
|
Bucket: this._bucket,
|
|
@@ -151,19 +198,29 @@ class S3Handler extends _abstract.default {
|
|
|
151
198
|
const splitPrefix = splitPath(prefix);
|
|
152
199
|
const result = await this._s3.listObjectsV2({
|
|
153
200
|
Bucket: this._bucket,
|
|
154
|
-
Prefix: splitPrefix.join('/')
|
|
201
|
+
Prefix: splitPrefix.join('/') + '/',
|
|
202
|
+
Delimiter: '/'
|
|
155
203
|
});
|
|
156
|
-
|
|
204
|
+
|
|
205
|
+
if (result.isTruncated) {
|
|
206
|
+
const error = new Error('more than 1000 objects, unsupported in this implementation');
|
|
207
|
+
error.dir = dir;
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const uniq = [];
|
|
212
|
+
|
|
213
|
+
for (const entry of result.CommonPrefixes) {
|
|
214
|
+
const line = splitPath(entry.Prefix);
|
|
215
|
+
uniq.push(line[line.length - 1]);
|
|
216
|
+
}
|
|
157
217
|
|
|
158
218
|
for (const entry of result.Contents) {
|
|
159
219
|
const line = splitPath(entry.Key);
|
|
160
|
-
|
|
161
|
-
if (line.length > splitPrefix.length) {
|
|
162
|
-
uniq.add(line[splitPrefix.length]);
|
|
163
|
-
}
|
|
220
|
+
uniq.push(line[line.length - 1]);
|
|
164
221
|
}
|
|
165
222
|
|
|
166
|
-
return
|
|
223
|
+
return uniq;
|
|
167
224
|
}
|
|
168
225
|
|
|
169
226
|
async _mkdir(path) {
|
|
@@ -176,41 +233,7 @@ class S3Handler extends _abstract.default {
|
|
|
176
233
|
}
|
|
177
234
|
|
|
178
235
|
async _rename(oldPath, newPath) {
|
|
179
|
-
|
|
180
|
-
const multipartParams = await this._s3.createMultipartUpload({ ...this._createParams(newPath)
|
|
181
|
-
});
|
|
182
|
-
const param2 = { ...multipartParams,
|
|
183
|
-
CopySource: `/${this._bucket}/${this._dir}${oldPath}`
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
try {
|
|
187
|
-
const parts = [];
|
|
188
|
-
let start = 0;
|
|
189
|
-
|
|
190
|
-
while (start < size) {
|
|
191
|
-
const range = `bytes=${start}-${Math.min(start + MAX_PART_SIZE, size) - 1}`;
|
|
192
|
-
const partParams = { ...param2,
|
|
193
|
-
PartNumber: parts.length + 1,
|
|
194
|
-
CopySourceRange: range
|
|
195
|
-
};
|
|
196
|
-
const upload = await this._s3.uploadPartCopy(partParams);
|
|
197
|
-
parts.push({
|
|
198
|
-
ETag: upload.CopyPartResult.ETag,
|
|
199
|
-
PartNumber: partParams.PartNumber
|
|
200
|
-
});
|
|
201
|
-
start += MAX_PART_SIZE;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
await this._s3.completeMultipartUpload({ ...multipartParams,
|
|
205
|
-
MultipartUpload: {
|
|
206
|
-
Parts: parts
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
} catch (e) {
|
|
210
|
-
await this._s3.abortMultipartUpload(multipartParams);
|
|
211
|
-
throw e;
|
|
212
|
-
}
|
|
213
|
-
|
|
236
|
+
await this.copy(oldPath, newPath);
|
|
214
237
|
await this._s3.deleteObject(this._createParams(oldPath));
|
|
215
238
|
}
|
|
216
239
|
|
|
@@ -231,12 +254,26 @@ class S3Handler extends _abstract.default {
|
|
|
231
254
|
const params = this._createParams(file);
|
|
232
255
|
|
|
233
256
|
params.Range = `bytes=${position}-${position + buffer.length - 1}`;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
const result = await this._s3.getObject(params);
|
|
260
|
+
result.Body.copy(buffer);
|
|
261
|
+
return {
|
|
262
|
+
bytesRead: result.Body.length,
|
|
263
|
+
buffer
|
|
264
|
+
};
|
|
265
|
+
} catch (e) {
|
|
266
|
+
if (e.code === 'NoSuchKey') {
|
|
267
|
+
if (await this._isNotEmptyDir(file)) {
|
|
268
|
+
const error = new Error(`${file} is a directory`);
|
|
269
|
+
error.code = 'EISDIR';
|
|
270
|
+
error.path = file;
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
throw e;
|
|
276
|
+
}
|
|
240
277
|
}
|
|
241
278
|
|
|
242
279
|
async _rmdir(path) {
|
|
@@ -248,6 +285,28 @@ class S3Handler extends _abstract.default {
|
|
|
248
285
|
}
|
|
249
286
|
}
|
|
250
287
|
|
|
288
|
+
async _rmtree(path) {
|
|
289
|
+
let NextContinuationToken;
|
|
290
|
+
|
|
291
|
+
do {
|
|
292
|
+
const result = await this._s3.listObjectsV2({
|
|
293
|
+
Bucket: this._bucket,
|
|
294
|
+
Prefix: this._dir + path + '/',
|
|
295
|
+
ContinuationToken: NextContinuationToken
|
|
296
|
+
});
|
|
297
|
+
NextContinuationToken = result.isTruncated ? null : result.NextContinuationToken;
|
|
298
|
+
|
|
299
|
+
for (const {
|
|
300
|
+
Key
|
|
301
|
+
} of result.Contents) {
|
|
302
|
+
await this._s3.deleteObject({
|
|
303
|
+
Bucket: this._bucket,
|
|
304
|
+
Key
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
} while (NextContinuationToken !== null);
|
|
308
|
+
}
|
|
309
|
+
|
|
251
310
|
async _write(file, buffer, position) {
|
|
252
311
|
if (typeof file !== 'string') {
|
|
253
312
|
file = file.fd;
|
package/dist/s3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/s3.js"],"names":["MIN_PART_SIZE","MAX_PART_SIZE","MAX_PARTS_COUNT","MAX_OBJECT_SIZE","IDEAL_FRAGMENT_SIZE","Math","ceil","S3Handler","RemoteHandlerAbstract","constructor","remote","_opts","host","path","username","password","protocol","region","url","params","accessKeyId","apiVersion","endpoint","s3ForcePathStyle","secretAccessKey","signatureVersion","httpOptions","timeout","agent","http","Agent","sslEnabled","undefined","_s3","s3","splitPath","split","filter","s","length","_bucket","shift","_dir","join","type","_createParams","file","Bucket","Key","_isNotEmptyDir","result","listObjectsV2","MaxKeys","Prefix","Contents","_isFile","headObject","error","code","_outputStream","input","validator","upload","Body","partSize","queueSize","call","unlink","_writeFile","data","options","putObject","_createReadStream","Error","getObject","raw","createReadStream","_unlink","deleteObject","_list","dir","d","prefix","splitPrefix","uniq","Set","entry","line","add","_mkdir","_rename","oldPath","newPath","size","_getSize","multipartParams","createMultipartUpload","param2","CopySource","parts","start","range","min","partParams","PartNumber","CopySourceRange","uploadPartCopy","push","ETag","CopyPartResult","completeMultipartUpload","MultipartUpload","Parts","e","abortMultipartUpload","fd","ContentLength","_read","buffer","position","Range","copy","bytesRead","_rmdir","_write","uploadParams","fileSize","resultBuffer","Buffer","alloc","max","fileContent","bytesWritten","copyMultipartParams","prefixSize","suffixOffset","suffixSize","hasSuffix","editBuffer","editBufferOffset","partNumber","prefixPosition","fragmentsCount","floor","prefixFragmentSize","prefixLastFragmentSize","i","fragmentEnd","assert","strictEqual","copyPrefixParams","part","downloadParams","prefixBuffer","concat","complementSize","complementOffset","prefixRange","complementBuffer","editParams","editPart","uploadPart","suffixFragments","suffixFragmentOffset","suffixRange","copySuffixParams","suffixPart","_openFile","flags","_closeFile"],"mappings":"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","sourcesContent":["import aws from '@sullux/aws-sdk'\nimport assert from 'assert'\nimport http from 'http'\nimport { parse } from 'xo-remote-parser'\n\nimport RemoteHandlerAbstract from './abstract'\n\n// endpoints https://docs.aws.amazon.com/general/latest/gr/s3.html\n\n// limits: https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html\nconst MIN_PART_SIZE = 1024 * 1024 * 5 // 5MB\nconst MAX_PART_SIZE = 1024 * 1024 * 1024 * 5 // 5GB\nconst MAX_PARTS_COUNT = 10000\nconst MAX_OBJECT_SIZE = 1024 * 1024 * 1024 * 1024 * 5 // 5TB\nconst IDEAL_FRAGMENT_SIZE = Math.ceil(MAX_OBJECT_SIZE / MAX_PARTS_COUNT) // the smallest fragment size that still allows a 5TB upload in 10000 fragments, about 524MB\nexport default class S3Handler extends RemoteHandlerAbstract {\n constructor(remote, _opts) {\n super(remote)\n const { host, path, username, password, protocol, region } = parse(remote.url)\n const params = {\n accessKeyId: username,\n apiVersion: '2006-03-01',\n endpoint: host,\n s3ForcePathStyle: true,\n secretAccessKey: password,\n signatureVersion: 'v4',\n httpOptions: {\n timeout: 600000,\n },\n }\n if (protocol === 'http') {\n params.httpOptions.agent = new http.Agent()\n params.sslEnabled = false\n }\n if (region !== undefined) {\n params.region = region\n }\n\n this._s3 = aws(params).s3\n\n const splitPath = path.split('/').filter(s => s.length)\n this._bucket = splitPath.shift()\n this._dir = splitPath.join('/')\n }\n\n get type() {\n return 's3'\n }\n\n _createParams(file) {\n return { Bucket: this._bucket, Key: this._dir + file }\n }\n\n async _isNotEmptyDir(path) {\n const result = await this._s3.listObjectsV2({\n Bucket: this._bucket,\n MaxKeys: 1,\n Prefix: this._dir + path + '/',\n })\n return result.Contents.length !== 0\n }\n\n async _isFile(path) {\n try {\n await this._s3.headObject(this._createParams(path))\n return true\n } catch (error) {\n if (error.code === 'NotFound') {\n return false\n }\n throw error\n }\n }\n\n async _outputStream(path, input, { validator }) {\n await this._s3.upload(\n {\n ...this._createParams(path),\n Body: input,\n },\n { partSize: IDEAL_FRAGMENT_SIZE, queueSize: 1 }\n )\n if (validator !== undefined) {\n try {\n await validator.call(this, path)\n } catch (error) {\n await this.unlink(path)\n throw error\n }\n }\n }\n\n async _writeFile(file, data, options) {\n return this._s3.putObject({ ...this._createParams(file), Body: data })\n }\n\n async _createReadStream(path, options) {\n if (!(await this._isFile(path))) {\n const error = new Error(`ENOENT: no such file '${path}'`)\n error.code = 'ENOENT'\n error.path = path\n throw error\n }\n\n // https://github.com/Sullux/aws-sdk/issues/11\n return this._s3.getObject.raw(this._createParams(path)).createReadStream()\n }\n\n async _unlink(path) {\n await this._s3.deleteObject(this._createParams(path))\n if (await this._isNotEmptyDir(path)) {\n const error = new Error(`EISDIR: illegal operation on a directory, unlink '${path}'`)\n error.code = 'EISDIR'\n error.path = path\n throw error\n }\n }\n\n async _list(dir) {\n function splitPath(path) {\n return path.split('/').filter(d => d.length)\n }\n\n const prefix = [this._dir, dir].join('/')\n const splitPrefix = splitPath(prefix)\n const result = await this._s3.listObjectsV2({\n Bucket: this._bucket,\n Prefix: splitPrefix.join('/'),\n })\n const uniq = new Set()\n for (const entry of result.Contents) {\n const line = splitPath(entry.Key)\n if (line.length > splitPrefix.length) {\n uniq.add(line[splitPrefix.length])\n }\n }\n return [...uniq]\n }\n\n async _mkdir(path) {\n if (await this._isFile(path)) {\n const error = new Error(`ENOTDIR: file already exists, mkdir '${path}'`)\n error.code = 'ENOTDIR'\n error.path = path\n throw error\n }\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n async _rename(oldPath, newPath) {\n const size = await this._getSize(oldPath)\n const multipartParams = await this._s3.createMultipartUpload({ ...this._createParams(newPath) })\n const param2 = { ...multipartParams, CopySource: `/${this._bucket}/${this._dir}${oldPath}` }\n try {\n const parts = []\n let start = 0\n while (start < size) {\n const range = `bytes=${start}-${Math.min(start + MAX_PART_SIZE, size) - 1}`\n const partParams = { ...param2, PartNumber: parts.length + 1, CopySourceRange: range }\n const upload = await this._s3.uploadPartCopy(partParams)\n parts.push({ ETag: upload.CopyPartResult.ETag, PartNumber: partParams.PartNumber })\n start += MAX_PART_SIZE\n }\n await this._s3.completeMultipartUpload({ ...multipartParams, MultipartUpload: { Parts: parts } })\n } catch (e) {\n await this._s3.abortMultipartUpload(multipartParams)\n throw e\n }\n await this._s3.deleteObject(this._createParams(oldPath))\n }\n\n async _getSize(file) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const result = await this._s3.headObject(this._createParams(file))\n return +result.ContentLength\n }\n\n async _read(file, buffer, position = 0) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const params = this._createParams(file)\n params.Range = `bytes=${position}-${position + buffer.length - 1}`\n const result = await this._s3.getObject(params)\n result.Body.copy(buffer)\n return { bytesRead: result.Body.length, buffer }\n }\n\n async _rmdir(path) {\n if (await this._isNotEmptyDir(path)) {\n const error = new Error(`ENOTEMPTY: directory not empty, rmdir '${path}`)\n error.code = 'ENOTEMPTY'\n error.path = path\n throw error\n }\n\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n async _write(file, buffer, position) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const uploadParams = this._createParams(file)\n let fileSize\n try {\n fileSize = +(await this._s3.headObject(uploadParams)).ContentLength\n } catch (e) {\n if (e.code === 'NotFound') {\n fileSize = 0\n } else {\n throw e\n }\n }\n if (fileSize < MIN_PART_SIZE) {\n const resultBuffer = Buffer.alloc(Math.max(fileSize, position + buffer.length))\n const fileContent = fileSize !== 0 ? (await this._s3.getObject(uploadParams)).Body : Buffer.alloc(0)\n fileContent.copy(resultBuffer)\n buffer.copy(resultBuffer, position)\n await this._s3.putObject({ ...uploadParams, Body: resultBuffer })\n return { buffer, bytesWritten: buffer.length }\n } else {\n // using this trick: https://stackoverflow.com/a/38089437/72637\n // multipart fragments have a minimum size of 5Mo and a max of 5Go unless they are last\n // splitting the file in 3 parts: [prefix, edit, suffix]\n // if `prefix` is bigger than 5Mo, it will be sourced from uploadPartCopy()\n // otherwise otherwise it will be downloaded, concatenated to `edit`\n // `edit` will always be an upload part\n // `suffix` will always be sourced from uploadPartCopy()\n // Then everything will be sliced in 5Gb parts before getting uploaded\n const multipartParams = await this._s3.createMultipartUpload(uploadParams)\n const copyMultipartParams = {\n ...multipartParams,\n CopySource: `/${this._bucket}/${this._dir + file}`,\n }\n try {\n const parts = []\n const prefixSize = position\n let suffixOffset = prefixSize + buffer.length\n let suffixSize = Math.max(0, fileSize - suffixOffset)\n let hasSuffix = suffixSize > 0\n let editBuffer = buffer\n let editBufferOffset = position\n let partNumber = 1\n let prefixPosition = 0\n // use floor() so that last fragment is handled in the if bellow\n let fragmentsCount = Math.floor(prefixSize / MAX_PART_SIZE)\n const prefixFragmentSize = MAX_PART_SIZE\n let prefixLastFragmentSize = prefixSize - prefixFragmentSize * fragmentsCount\n if (prefixLastFragmentSize >= MIN_PART_SIZE) {\n // the last fragment of the prefix is smaller than MAX_PART_SIZE, but bigger than the minimum\n // so we can copy it too\n fragmentsCount++\n prefixLastFragmentSize = 0\n }\n for (let i = 0; i < fragmentsCount; i++) {\n const fragmentEnd = Math.min(prefixPosition + prefixFragmentSize, prefixSize)\n assert.strictEqual(fragmentEnd - prefixPosition <= MAX_PART_SIZE, true)\n const range = `bytes=${prefixPosition}-${fragmentEnd - 1}`\n const copyPrefixParams = { ...copyMultipartParams, PartNumber: partNumber++, CopySourceRange: range }\n const part = await this._s3.uploadPartCopy(copyPrefixParams)\n parts.push({ ETag: part.CopyPartResult.ETag, PartNumber: copyPrefixParams.PartNumber })\n prefixPosition += prefixFragmentSize\n }\n if (prefixLastFragmentSize) {\n // grab everything from the prefix that was too small to be copied, download and merge to the edit buffer.\n const downloadParams = { ...uploadParams, Range: `bytes=${prefixPosition}-${prefixSize - 1}` }\n const prefixBuffer = prefixSize > 0 ? (await this._s3.getObject(downloadParams)).Body : Buffer.alloc(0)\n editBuffer = Buffer.concat([prefixBuffer, buffer])\n editBufferOffset -= prefixLastFragmentSize\n }\n if (hasSuffix && editBuffer.length < MIN_PART_SIZE) {\n // the edit fragment is too short and is not the last fragment\n // let's steal from the suffix fragment to reach the minimum size\n // the suffix might be too short and itself entirely absorbed in the edit fragment, making it the last one.\n const complementSize = Math.min(MIN_PART_SIZE - editBuffer.length, suffixSize)\n const complementOffset = editBufferOffset + editBuffer.length\n suffixOffset += complementSize\n suffixSize -= complementSize\n hasSuffix = suffixSize > 0\n const prefixRange = `bytes=${complementOffset}-${complementOffset + complementSize - 1}`\n const downloadParams = { ...uploadParams, Range: prefixRange }\n const complementBuffer = (await this._s3.getObject(downloadParams)).Body\n editBuffer = Buffer.concat([editBuffer, complementBuffer])\n }\n const editParams = { ...multipartParams, Body: editBuffer, PartNumber: partNumber++ }\n const editPart = await this._s3.uploadPart(editParams)\n parts.push({ ETag: editPart.ETag, PartNumber: editParams.PartNumber })\n if (hasSuffix) {\n // use ceil because the last fragment can be arbitrarily small.\n const suffixFragments = Math.ceil(suffixSize / MAX_PART_SIZE)\n let suffixFragmentOffset = suffixOffset\n for (let i = 0; i < suffixFragments; i++) {\n const fragmentEnd = suffixFragmentOffset + MAX_PART_SIZE\n assert.strictEqual(Math.min(fileSize, fragmentEnd) - suffixFragmentOffset <= MAX_PART_SIZE, true)\n const suffixRange = `bytes=${suffixFragmentOffset}-${Math.min(fileSize, fragmentEnd) - 1}`\n const copySuffixParams = { ...copyMultipartParams, PartNumber: partNumber++, CopySourceRange: suffixRange }\n const suffixPart = (await this._s3.uploadPartCopy(copySuffixParams)).CopyPartResult\n parts.push({ ETag: suffixPart.ETag, PartNumber: copySuffixParams.PartNumber })\n suffixFragmentOffset = fragmentEnd\n }\n }\n await this._s3.completeMultipartUpload({\n ...multipartParams,\n MultipartUpload: { Parts: parts },\n })\n } catch (e) {\n await this._s3.abortMultipartUpload(multipartParams)\n throw e\n }\n }\n }\n\n async _openFile(path, flags) {\n return path\n }\n\n async _closeFile(fd) {}\n}\n"],"file":"s3.js"}
|
|
1
|
+
{"version":3,"sources":["../src/s3.js"],"names":["MIN_PART_SIZE","MAX_PART_SIZE","MAX_PARTS_COUNT","MAX_OBJECT_SIZE","IDEAL_FRAGMENT_SIZE","Math","ceil","S3Handler","RemoteHandlerAbstract","constructor","remote","_opts","allowUnauthorized","host","path","username","password","protocol","region","url","params","accessKeyId","apiVersion","endpoint","s3ForcePathStyle","secretAccessKey","signatureVersion","httpOptions","timeout","agent","http","Agent","keepAlive","sslEnabled","https","rejectUnauthorized","undefined","_s3","s3","splitPath","split","filter","s","length","_bucket","shift","_dir","join","type","_createParams","file","Bucket","Key","_copy","oldPath","newPath","size","_getSize","multipartParams","createMultipartUpload","param2","CopySource","parts","start","range","min","partParams","PartNumber","CopySourceRange","upload","uploadPartCopy","push","ETag","CopyPartResult","completeMultipartUpload","MultipartUpload","Parts","e","abortMultipartUpload","_isNotEmptyDir","result","listObjectsV2","MaxKeys","Prefix","Contents","_isFile","headObject","error","code","_outputStream","input","validator","Body","partSize","queueSize","call","unlink","_writeFile","data","options","putObject","_createReadStream","Error","getObject","raw","createReadStream","_unlink","deleteObject","_list","dir","d","prefix","splitPrefix","Delimiter","isTruncated","uniq","entry","CommonPrefixes","line","_mkdir","_rename","copy","fd","ContentLength","_read","buffer","position","Range","bytesRead","_rmdir","_rmtree","NextContinuationToken","ContinuationToken","_write","uploadParams","fileSize","resultBuffer","Buffer","alloc","max","fileContent","bytesWritten","copyMultipartParams","prefixSize","suffixOffset","suffixSize","hasSuffix","editBuffer","editBufferOffset","partNumber","prefixPosition","fragmentsCount","floor","prefixFragmentSize","prefixLastFragmentSize","i","fragmentEnd","assert","strictEqual","copyPrefixParams","part","downloadParams","prefixBuffer","concat","complementSize","complementOffset","prefixRange","complementBuffer","editParams","editPart","uploadPart","suffixFragments","suffixFragmentOffset","suffixRange","copySuffixParams","suffixPart","_openFile","flags","_closeFile"],"mappings":"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","sourcesContent":["import aws from '@sullux/aws-sdk'\nimport assert from 'assert'\nimport http from 'http'\nimport https from 'https'\nimport { parse } from 'xo-remote-parser'\n\nimport RemoteHandlerAbstract from './abstract'\n\n// endpoints https://docs.aws.amazon.com/general/latest/gr/s3.html\n\n// limits: https://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html\nconst MIN_PART_SIZE = 1024 * 1024 * 5 // 5MB\nconst MAX_PART_SIZE = 1024 * 1024 * 1024 * 5 // 5GB\nconst MAX_PARTS_COUNT = 10000\nconst MAX_OBJECT_SIZE = 1024 * 1024 * 1024 * 1024 * 5 // 5TB\nconst IDEAL_FRAGMENT_SIZE = Math.ceil(MAX_OBJECT_SIZE / MAX_PARTS_COUNT) // the smallest fragment size that still allows a 5TB upload in 10000 fragments, about 524MB\nexport default class S3Handler extends RemoteHandlerAbstract {\n constructor(remote, _opts) {\n super(remote)\n const { allowUnauthorized, host, path, username, password, protocol, region } = parse(remote.url)\n const params = {\n accessKeyId: username,\n apiVersion: '2006-03-01',\n endpoint: host,\n s3ForcePathStyle: true,\n secretAccessKey: password,\n signatureVersion: 'v4',\n httpOptions: {\n timeout: 600000,\n },\n }\n if (protocol === 'http') {\n params.httpOptions.agent = new http.Agent({ keepAlive: true })\n params.sslEnabled = false\n } else if (protocol === 'https') {\n params.httpOptions.agent = new https.Agent({\n rejectUnauthorized: !allowUnauthorized,\n keepAlive: true,\n })\n }\n if (region !== undefined) {\n params.region = region\n }\n\n this._s3 = aws(params).s3\n\n const splitPath = path.split('/').filter(s => s.length)\n this._bucket = splitPath.shift()\n this._dir = splitPath.join('/')\n }\n\n get type() {\n return 's3'\n }\n\n _createParams(file) {\n return { Bucket: this._bucket, Key: this._dir + file }\n }\n\n async _copy(oldPath, newPath) {\n const size = await this._getSize(oldPath)\n const multipartParams = await this._s3.createMultipartUpload({ ...this._createParams(newPath) })\n const param2 = { ...multipartParams, CopySource: `/${this._bucket}/${this._dir}${oldPath}` }\n try {\n const parts = []\n let start = 0\n while (start < size) {\n const range = `bytes=${start}-${Math.min(start + MAX_PART_SIZE, size) - 1}`\n const partParams = { ...param2, PartNumber: parts.length + 1, CopySourceRange: range }\n const upload = await this._s3.uploadPartCopy(partParams)\n parts.push({ ETag: upload.CopyPartResult.ETag, PartNumber: partParams.PartNumber })\n start += MAX_PART_SIZE\n }\n await this._s3.completeMultipartUpload({ ...multipartParams, MultipartUpload: { Parts: parts } })\n } catch (e) {\n await this._s3.abortMultipartUpload(multipartParams)\n throw e\n }\n }\n\n async _isNotEmptyDir(path) {\n const result = await this._s3.listObjectsV2({\n Bucket: this._bucket,\n MaxKeys: 1,\n Prefix: this._dir + path + '/',\n })\n return result.Contents.length !== 0\n }\n\n async _isFile(path) {\n try {\n await this._s3.headObject(this._createParams(path))\n return true\n } catch (error) {\n if (error.code === 'NotFound') {\n return false\n }\n throw error\n }\n }\n\n async _outputStream(path, input, { validator }) {\n await this._s3.upload(\n {\n ...this._createParams(path),\n Body: input,\n },\n { partSize: IDEAL_FRAGMENT_SIZE, queueSize: 1 }\n )\n if (validator !== undefined) {\n try {\n await validator.call(this, path)\n } catch (error) {\n await this.unlink(path)\n throw error\n }\n }\n }\n\n async _writeFile(file, data, options) {\n return this._s3.putObject({ ...this._createParams(file), Body: data })\n }\n\n async _createReadStream(path, options) {\n if (!(await this._isFile(path))) {\n const error = new Error(`ENOENT: no such file '${path}'`)\n error.code = 'ENOENT'\n error.path = path\n throw error\n }\n\n // https://github.com/Sullux/aws-sdk/issues/11\n return this._s3.getObject.raw(this._createParams(path)).createReadStream()\n }\n\n async _unlink(path) {\n await this._s3.deleteObject(this._createParams(path))\n if (await this._isNotEmptyDir(path)) {\n const error = new Error(`EISDIR: illegal operation on a directory, unlink '${path}'`)\n error.code = 'EISDIR'\n error.path = path\n throw error\n }\n }\n\n async _list(dir) {\n function splitPath(path) {\n return path.split('/').filter(d => d.length)\n }\n\n const prefix = [this._dir, dir].join('/')\n const splitPrefix = splitPath(prefix)\n const result = await this._s3.listObjectsV2({\n Bucket: this._bucket,\n Prefix: splitPrefix.join('/') + '/', // need slash at the end with the use of delimiters\n Delimiter: '/', // will only return path until delimiters\n })\n\n if (result.isTruncated) {\n const error = new Error('more than 1000 objects, unsupported in this implementation')\n error.dir = dir\n throw error\n }\n\n const uniq = []\n\n // sub directories\n for (const entry of result.CommonPrefixes) {\n const line = splitPath(entry.Prefix)\n uniq.push(line[line.length - 1])\n }\n // files\n for (const entry of result.Contents) {\n const line = splitPath(entry.Key)\n uniq.push(line[line.length - 1])\n }\n\n return uniq\n }\n\n async _mkdir(path) {\n if (await this._isFile(path)) {\n const error = new Error(`ENOTDIR: file already exists, mkdir '${path}'`)\n error.code = 'ENOTDIR'\n error.path = path\n throw error\n }\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n // s3 doesn't have a rename operation, so copy + delete source\n async _rename(oldPath, newPath) {\n await this.copy(oldPath, newPath)\n await this._s3.deleteObject(this._createParams(oldPath))\n }\n\n async _getSize(file) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const result = await this._s3.headObject(this._createParams(file))\n return +result.ContentLength\n }\n\n async _read(file, buffer, position = 0) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const params = this._createParams(file)\n params.Range = `bytes=${position}-${position + buffer.length - 1}`\n try {\n const result = await this._s3.getObject(params)\n result.Body.copy(buffer)\n return { bytesRead: result.Body.length, buffer }\n } catch (e) {\n if (e.code === 'NoSuchKey') {\n if (await this._isNotEmptyDir(file)) {\n const error = new Error(`${file} is a directory`)\n error.code = 'EISDIR'\n error.path = file\n throw error\n }\n }\n throw e\n }\n }\n\n async _rmdir(path) {\n if (await this._isNotEmptyDir(path)) {\n const error = new Error(`ENOTEMPTY: directory not empty, rmdir '${path}`)\n error.code = 'ENOTEMPTY'\n error.path = path\n throw error\n }\n\n // nothing to do, directories do not exist, they are part of the files' path\n }\n\n // reimplement _rmtree to handle efficiantly path with more than 1000 entries in trees\n // @todo : use parallel processing for unlink\n async _rmtree(path) {\n let NextContinuationToken\n do {\n const result = await this._s3.listObjectsV2({\n Bucket: this._bucket,\n Prefix: this._dir + path + '/',\n ContinuationToken: NextContinuationToken,\n })\n NextContinuationToken = result.isTruncated ? null : result.NextContinuationToken\n for (const { Key } of result.Contents) {\n // _unlink will add the prefix, but Key contains everything\n // also we don't need to check if we delete a directory, since the list only return files\n await this._s3.deleteObject({\n Bucket: this._bucket,\n Key,\n })\n }\n } while (NextContinuationToken !== null)\n }\n\n async _write(file, buffer, position) {\n if (typeof file !== 'string') {\n file = file.fd\n }\n const uploadParams = this._createParams(file)\n let fileSize\n try {\n fileSize = +(await this._s3.headObject(uploadParams)).ContentLength\n } catch (e) {\n if (e.code === 'NotFound') {\n fileSize = 0\n } else {\n throw e\n }\n }\n if (fileSize < MIN_PART_SIZE) {\n const resultBuffer = Buffer.alloc(Math.max(fileSize, position + buffer.length))\n const fileContent = fileSize !== 0 ? (await this._s3.getObject(uploadParams)).Body : Buffer.alloc(0)\n fileContent.copy(resultBuffer)\n buffer.copy(resultBuffer, position)\n await this._s3.putObject({ ...uploadParams, Body: resultBuffer })\n return { buffer, bytesWritten: buffer.length }\n } else {\n // using this trick: https://stackoverflow.com/a/38089437/72637\n // multipart fragments have a minimum size of 5Mo and a max of 5Go unless they are last\n // splitting the file in 3 parts: [prefix, edit, suffix]\n // if `prefix` is bigger than 5Mo, it will be sourced from uploadPartCopy()\n // otherwise otherwise it will be downloaded, concatenated to `edit`\n // `edit` will always be an upload part\n // `suffix` will always be sourced from uploadPartCopy()\n // Then everything will be sliced in 5Gb parts before getting uploaded\n const multipartParams = await this._s3.createMultipartUpload(uploadParams)\n const copyMultipartParams = {\n ...multipartParams,\n CopySource: `/${this._bucket}/${this._dir + file}`,\n }\n try {\n const parts = []\n const prefixSize = position\n let suffixOffset = prefixSize + buffer.length\n let suffixSize = Math.max(0, fileSize - suffixOffset)\n let hasSuffix = suffixSize > 0\n let editBuffer = buffer\n let editBufferOffset = position\n let partNumber = 1\n let prefixPosition = 0\n // use floor() so that last fragment is handled in the if bellow\n let fragmentsCount = Math.floor(prefixSize / MAX_PART_SIZE)\n const prefixFragmentSize = MAX_PART_SIZE\n let prefixLastFragmentSize = prefixSize - prefixFragmentSize * fragmentsCount\n if (prefixLastFragmentSize >= MIN_PART_SIZE) {\n // the last fragment of the prefix is smaller than MAX_PART_SIZE, but bigger than the minimum\n // so we can copy it too\n fragmentsCount++\n prefixLastFragmentSize = 0\n }\n for (let i = 0; i < fragmentsCount; i++) {\n const fragmentEnd = Math.min(prefixPosition + prefixFragmentSize, prefixSize)\n assert.strictEqual(fragmentEnd - prefixPosition <= MAX_PART_SIZE, true)\n const range = `bytes=${prefixPosition}-${fragmentEnd - 1}`\n const copyPrefixParams = { ...copyMultipartParams, PartNumber: partNumber++, CopySourceRange: range }\n const part = await this._s3.uploadPartCopy(copyPrefixParams)\n parts.push({ ETag: part.CopyPartResult.ETag, PartNumber: copyPrefixParams.PartNumber })\n prefixPosition += prefixFragmentSize\n }\n if (prefixLastFragmentSize) {\n // grab everything from the prefix that was too small to be copied, download and merge to the edit buffer.\n const downloadParams = { ...uploadParams, Range: `bytes=${prefixPosition}-${prefixSize - 1}` }\n const prefixBuffer = prefixSize > 0 ? (await this._s3.getObject(downloadParams)).Body : Buffer.alloc(0)\n editBuffer = Buffer.concat([prefixBuffer, buffer])\n editBufferOffset -= prefixLastFragmentSize\n }\n if (hasSuffix && editBuffer.length < MIN_PART_SIZE) {\n // the edit fragment is too short and is not the last fragment\n // let's steal from the suffix fragment to reach the minimum size\n // the suffix might be too short and itself entirely absorbed in the edit fragment, making it the last one.\n const complementSize = Math.min(MIN_PART_SIZE - editBuffer.length, suffixSize)\n const complementOffset = editBufferOffset + editBuffer.length\n suffixOffset += complementSize\n suffixSize -= complementSize\n hasSuffix = suffixSize > 0\n const prefixRange = `bytes=${complementOffset}-${complementOffset + complementSize - 1}`\n const downloadParams = { ...uploadParams, Range: prefixRange }\n const complementBuffer = (await this._s3.getObject(downloadParams)).Body\n editBuffer = Buffer.concat([editBuffer, complementBuffer])\n }\n const editParams = { ...multipartParams, Body: editBuffer, PartNumber: partNumber++ }\n const editPart = await this._s3.uploadPart(editParams)\n parts.push({ ETag: editPart.ETag, PartNumber: editParams.PartNumber })\n if (hasSuffix) {\n // use ceil because the last fragment can be arbitrarily small.\n const suffixFragments = Math.ceil(suffixSize / MAX_PART_SIZE)\n let suffixFragmentOffset = suffixOffset\n for (let i = 0; i < suffixFragments; i++) {\n const fragmentEnd = suffixFragmentOffset + MAX_PART_SIZE\n assert.strictEqual(Math.min(fileSize, fragmentEnd) - suffixFragmentOffset <= MAX_PART_SIZE, true)\n const suffixRange = `bytes=${suffixFragmentOffset}-${Math.min(fileSize, fragmentEnd) - 1}`\n const copySuffixParams = { ...copyMultipartParams, PartNumber: partNumber++, CopySourceRange: suffixRange }\n const suffixPart = (await this._s3.uploadPartCopy(copySuffixParams)).CopyPartResult\n parts.push({ ETag: suffixPart.ETag, PartNumber: copySuffixParams.PartNumber })\n suffixFragmentOffset = fragmentEnd\n }\n }\n await this._s3.completeMultipartUpload({\n ...multipartParams,\n MultipartUpload: { Parts: parts },\n })\n } catch (e) {\n await this._s3.abortMultipartUpload(multipartParams)\n throw e\n }\n }\n }\n\n async _openFile(path, flags) {\n return path\n }\n\n async _closeFile(fd) {}\n}\n"],"file":"s3.js"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@xen-orchestra/fs",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.19.2",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"description": "The File System for Xen Orchestra backups.",
|
|
7
7
|
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/fs",
|
|
@@ -17,23 +17,23 @@
|
|
|
17
17
|
"node": ">=14"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@marsaud/smb2": "^0.
|
|
20
|
+
"@marsaud/smb2": "^0.18.0",
|
|
21
21
|
"@sindresorhus/df": "^3.1.1",
|
|
22
22
|
"@sullux/aws-sdk": "^1.0.5",
|
|
23
23
|
"@vates/coalesce-calls": "^0.1.0",
|
|
24
24
|
"@xen-orchestra/async-map": "^0.1.2",
|
|
25
25
|
"aws-sdk": "^2.686.0",
|
|
26
|
-
"decorator-synchronized": "^0.
|
|
26
|
+
"decorator-synchronized": "^0.6.0",
|
|
27
27
|
"execa": "^5.0.0",
|
|
28
|
-
"fs-extra": "^
|
|
28
|
+
"fs-extra": "^10.0.0",
|
|
29
29
|
"get-stream": "^6.0.0",
|
|
30
|
-
"limit-concurrency-decorator": "^0.
|
|
30
|
+
"limit-concurrency-decorator": "^0.5.0",
|
|
31
31
|
"lodash": "^4.17.4",
|
|
32
|
-
"promise-toolbox": "^0.
|
|
32
|
+
"promise-toolbox": "^0.20.0",
|
|
33
33
|
"proper-lockfile": "^4.1.2",
|
|
34
34
|
"readable-stream": "^3.0.6",
|
|
35
35
|
"through2": "^4.0.2",
|
|
36
|
-
"xo-remote-parser": "^0.
|
|
36
|
+
"xo-remote-parser": "^0.8.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@babel/cli": "^7.0.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"async-iterator-to-stream": "^1.1.0",
|
|
46
46
|
"babel-plugin-lodash": "^3.3.2",
|
|
47
47
|
"cross-env": "^7.0.2",
|
|
48
|
-
"dotenv": "^
|
|
48
|
+
"dotenv": "^10.0.0",
|
|
49
49
|
"rimraf": "^3.0.0"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
package/gitignore-test-s3.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
|
|
3
|
-
try {
|
|
4
|
-
Error.stackTraceLimit = 20
|
|
5
|
-
|
|
6
|
-
require('source-map-support/register.js')
|
|
7
|
-
} catch (error) {
|
|
8
|
-
console.warn(error)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const repl = async ({ prompt, context } = {}) => {
|
|
12
|
-
const repl = require('repl').start({ prompt })
|
|
13
|
-
if (context !== undefined) {
|
|
14
|
-
Object.defineProperties(repl.context, Object.getOwnPropertyDescriptors(context))
|
|
15
|
-
}
|
|
16
|
-
const { eval: evaluate } = repl
|
|
17
|
-
repl.eval = (cmd, context, filename, cb) => {
|
|
18
|
-
evaluate.call(repl, cmd, context, filename, (error, result) => {
|
|
19
|
-
if (error != null) {
|
|
20
|
-
return cb(error)
|
|
21
|
-
}
|
|
22
|
-
Promise.resolve(result).then(result => cb(undefined, result), cb)
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
return require('promise-toolbox/fromEvent')(repl, 'exit')
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const main = require('golike-defer').defer(async function ($defer) {
|
|
29
|
-
const h = require('./').getHandler({ url: 's3+http://minioadmin:minioadmin@localhost:9001/xo-test-remote/foo' })
|
|
30
|
-
await h.sync()
|
|
31
|
-
$defer.call(h, 'forget')
|
|
32
|
-
await repl({ context: { h } })
|
|
33
|
-
})
|
|
34
|
-
main().catch(e => console.error('FATAL', e))
|