128 lines
3.0 KiB
JavaScript
128 lines
3.0 KiB
JavaScript
import df from '@sindresorhus/df'
|
|
import fs from 'fs-extra'
|
|
import { fromEvent } from 'promise-toolbox'
|
|
|
|
import RemoteHandlerAbstract from './abstract'
|
|
|
|
export default class LocalHandler extends RemoteHandlerAbstract {
|
|
get type() {
|
|
return 'file'
|
|
}
|
|
|
|
_getRealPath() {
|
|
return this._remote.path
|
|
}
|
|
|
|
_getFilePath(file) {
|
|
return this._getRealPath() + file
|
|
}
|
|
|
|
async _closeFile(fd) {
|
|
return fs.close(fd)
|
|
}
|
|
|
|
async _createReadStream(file, options) {
|
|
if (typeof file === 'string') {
|
|
const stream = fs.createReadStream(this._getFilePath(file), options)
|
|
await fromEvent(stream, 'open')
|
|
return stream
|
|
}
|
|
return fs.createReadStream('', {
|
|
autoClose: false,
|
|
...options,
|
|
fd: file.fd,
|
|
})
|
|
}
|
|
|
|
async _createWriteStream(file, options) {
|
|
if (typeof file === 'string') {
|
|
const stream = fs.createWriteStream(this._getFilePath(file), options)
|
|
await fromEvent(stream, 'open')
|
|
return stream
|
|
}
|
|
return fs.createWriteStream('', {
|
|
autoClose: false,
|
|
...options,
|
|
fd: file.fd,
|
|
})
|
|
}
|
|
|
|
async _getInfo() {
|
|
// df.file() resolves with an object with the following properties:
|
|
// filesystem, type, size, used, available, capacity and mountpoint.
|
|
// size, used, available and capacity may be `NaN` so we remove any `NaN`
|
|
// value from the object.
|
|
const info = await df.file(this._getFilePath('/'))
|
|
Object.keys(info).forEach(key => {
|
|
if (Number.isNaN(info[key])) {
|
|
delete info[key]
|
|
}
|
|
})
|
|
|
|
return info
|
|
}
|
|
|
|
async _getSize(file) {
|
|
const stats = await fs.stat(this._getFilePath(typeof file === 'string' ? file : file.path))
|
|
return stats.size
|
|
}
|
|
|
|
async _list(dir) {
|
|
return fs.readdir(this._getFilePath(dir))
|
|
}
|
|
|
|
_mkdir(dir, { mode }) {
|
|
return fs.mkdir(this._getFilePath(dir), { mode })
|
|
}
|
|
|
|
async _openFile(path, flags) {
|
|
return fs.open(this._getFilePath(path), flags)
|
|
}
|
|
|
|
async _read(file, buffer, position) {
|
|
const needsClose = typeof file === 'string'
|
|
file = needsClose ? await fs.open(this._getFilePath(file), 'r') : file.fd
|
|
try {
|
|
return await fs.read(file, buffer, 0, buffer.length, position === undefined ? null : position)
|
|
} finally {
|
|
if (needsClose) {
|
|
await fs.close(file)
|
|
}
|
|
}
|
|
}
|
|
|
|
async _readFile(file, options) {
|
|
return fs.readFile(this._getFilePath(file), options)
|
|
}
|
|
|
|
async _rename(oldPath, newPath) {
|
|
return fs.rename(this._getFilePath(oldPath), this._getFilePath(newPath))
|
|
}
|
|
|
|
async _rmdir(dir) {
|
|
return fs.rmdir(this._getFilePath(dir))
|
|
}
|
|
|
|
async _sync() {
|
|
const path = this._getRealPath('/')
|
|
await fs.ensureDir(path)
|
|
await fs.access(path, fs.R_OK | fs.W_OK)
|
|
}
|
|
|
|
_truncate(file, len) {
|
|
return fs.truncate(this._getFilePath(file), len)
|
|
}
|
|
|
|
async _unlink(file) {
|
|
return fs.unlink(this._getFilePath(file))
|
|
}
|
|
|
|
_writeFd(file, buffer, position) {
|
|
return fs.write(file.fd, buffer, 0, buffer.length, position)
|
|
}
|
|
|
|
_writeFile(file, data, { flags }) {
|
|
return fs.writeFile(this._getFilePath(file), data, { flag: flags })
|
|
}
|
|
}
|