Fixes #662: exchange var for const of require statements in src/filesystem/interface.js (#668)

* exchange var for const of require statements

Changed decleration of import files from var to const in interface.js

* Fixed all areas where var was used as well as use destructing assignment for  CONST imports.

* Fixed import const statement

* Added changes from let to const in certain lines
This commit is contained in:
Brandon Wissmann 2019-01-31 20:22:46 -05:00 committed by David Humphrey
parent 701849eb5a
commit 3b4bf42604
1 changed files with 125 additions and 120 deletions

View File

@ -1,38 +1,43 @@
var { promisify } = require('es6-promisify'); 'use strict';
var Path = require('../path.js'); const { promisify } = require('es6-promisify');
var nop = require('../shared.js').nop;
var Constants = require('../constants.js'); const Path = require('../path.js');
var FILE_SYSTEM_NAME = Constants.FILE_SYSTEM_NAME;
var FS_FORMAT = Constants.FS_FORMAT;
var FS_READY = Constants.FS_READY;
var FS_PENDING = Constants.FS_PENDING;
var FS_ERROR = Constants.FS_ERROR;
var FS_NODUPEIDCHECK = Constants.FS_NODUPEIDCHECK;
var providers = require('../providers/index.js'); const providers = require('../providers/index.js');
var Shell = require('../shell/shell.js'); const Shell = require('../shell/shell.js');
var Intercom = require('../../lib/intercom.js'); const Intercom = require('../../lib/intercom.js');
var FSWatcher = require('../fs-watcher.js'); const FSWatcher = require('../fs-watcher.js');
var Errors = require('../errors.js'); const Errors = require('../errors.js');
var defaultGuidFn = require('../shared.js').guid; const {
nop,
guid: defaultGuidFn
} = require('../shared.js');
var STDIN = Constants.STDIN; const {
var STDOUT = Constants.STDOUT; fsConstants,
var STDERR = Constants.STDERR; FILE_SYSTEM_NAME,
FS_FORMAT,
FS_READY,
FS_PENDING,
FS_ERROR,
FS_NODUPEIDCHECK,
STDIN,
STDOUT,
STDERR
} = require('../constants.js');
// The core fs operations live on impl // The core fs operations live on impl
var impl = require('./implementation.js'); const impl = require('./implementation.js');
// node.js supports a calling pattern that leaves off a callback. // node.js supports a calling pattern that leaves off a callback.
function maybeCallback(callback) { function maybeCallback(callback) {
if(typeof callback === 'function') { if (typeof callback === 'function') {
return callback; return callback;
} }
return function(err) { return function (err) {
if(err) { if (err) {
throw err; throw err;
} }
}; };
@ -40,7 +45,7 @@ function maybeCallback(callback) {
// Default callback that logs an error if passed in // Default callback that logs an error if passed in
function defaultCallback(err) { function defaultCallback(err) {
if(err) { if (err) {
/* eslint no-console: 0 */ /* eslint no-console: 0 */
console.error('Filer error: ', err); console.error('Filer error: ', err);
} }
@ -48,20 +53,20 @@ function defaultCallback(err) {
// Get a path (String) from a file:// URL. Support URL() like objects // Get a path (String) from a file:// URL. Support URL() like objects
// https://github.com/nodejs/node/blob/968e901aff38a343b1de4addebf79fd8fa991c59/lib/internal/url.js#L1381 // https://github.com/nodejs/node/blob/968e901aff38a343b1de4addebf79fd8fa991c59/lib/internal/url.js#L1381
function toPathIfFileURL(fileURLOrPath) { function toPathIfFileURL(fileURLOrPath) {
if(!(fileURLOrPath && if (!(fileURLOrPath &&
fileURLOrPath.protocol && fileURLOrPath.protocol &&
fileURLOrPath.pathname)) { fileURLOrPath.pathname)) {
return fileURLOrPath; return fileURLOrPath;
} }
if(fileURLOrPath.protocol !== 'file:') { if (fileURLOrPath.protocol !== 'file:') {
throw new Errors.EINVAL('only file: URLs are supported for paths', fileURLOrPath); throw new Errors.EINVAL('only file: URLs are supported for paths', fileURLOrPath);
} }
var pathname = fileURLOrPath.pathname; const pathname = fileURLOrPath.pathname;
for (var n = 0; n < pathname.length; n++) { for (let n = 0; n < pathname.length; n++) {
if (pathname[n] === '%') { if (pathname[n] === '%') {
var third = pathname.codePointAt(n + 2) | 0x20; const third = pathname.codePointAt(n + 2) | 0x20;
if (pathname[n + 1] === '2' && third === 102) { if (pathname[n + 1] === '2' && third === 102) {
throw new Errors.EINVAL('file: URLs must not include encoded / characters', fileURLOrPath); throw new Errors.EINVAL('file: URLs must not include encoded / characters', fileURLOrPath);
} }
@ -77,23 +82,23 @@ function toPathIfBuffer(bufferOrPath) {
} }
function validatePath(path, allowRelative) { function validatePath(path, allowRelative) {
if(!path) { if (!path) {
return new Errors.EINVAL('Path must be a string', path); return new Errors.EINVAL('Path must be a string', path);
} else if(Path.isNull(path)) { } else if (Path.isNull(path)) {
return new Errors.EINVAL('Path must be a string without null bytes.', path); return new Errors.EINVAL('Path must be a string without null bytes.', path);
} else if(!allowRelative && !Path.isAbsolute(path)) { } else if (!allowRelative && !Path.isAbsolute(path)) {
return new Errors.EINVAL('Path must be absolute.', path); return new Errors.EINVAL('Path must be absolute.', path);
} }
} }
function processPathArg(args, idx, allowRelative) { function processPathArg(args, idx, allowRelative) {
var path = args[idx]; let path = args[idx];
path = toPathIfFileURL(path); path = toPathIfFileURL(path);
path = toPathIfBuffer(path); path = toPathIfBuffer(path);
// Some methods specifically allow for rel paths (eg symlink with srcPath) // Some methods specifically allow for rel paths (eg symlink with srcPath)
var err = validatePath(path, allowRelative); let err = validatePath(path, allowRelative);
if(err) { if (err) {
throw err; throw err;
} }
@ -133,14 +138,14 @@ function FileSystem(options, callback) {
options = options || {}; options = options || {};
callback = callback || defaultCallback; callback = callback || defaultCallback;
var flags = options.flags || []; const flags = options.flags || [];
var guid = options.guid ? options.guid : defaultGuidFn; const guid = options.guid ? options.guid : defaultGuidFn;
var provider = options.provider || new providers.Default(options.name || FILE_SYSTEM_NAME); const provider = options.provider || new providers.Default(options.name || FILE_SYSTEM_NAME);
// If we're given a provider, match its name unless we get an explicit name // If we're given a provider, match its name unless we get an explicit name
var name = options.name || provider.name; const name = options.name || provider.name;
var forceFormatting = flags.includes(FS_FORMAT); const forceFormatting = flags.includes(FS_FORMAT);
var fs = this; const fs = this;
fs.readyState = FS_PENDING; fs.readyState = FS_PENDING;
fs.name = name; fs.name = name;
fs.error = null; fs.error = null;
@ -150,24 +155,24 @@ function FileSystem(options, callback) {
fs.stderr = STDERR; fs.stderr = STDERR;
// Expose Node's fs.constants to users // Expose Node's fs.constants to users
fs.constants = Constants.fsConstants; fs.constants = fsConstants;
// Node also forwards the access mode flags onto fs // Node also forwards the access mode flags onto fs
fs.F_OK = Constants.fsConstants.F_OK; fs.F_OK = fsConstants.F_OK;
fs.R_OK = Constants.fsConstants.R_OK; fs.R_OK = fsConstants.R_OK;
fs.W_OK = Constants.fsConstants.W_OK; fs.W_OK = fsConstants.W_OK;
fs.X_OK = Constants.fsConstants.X_OK; fs.X_OK = fsConstants.X_OK;
// Expose Shell constructor // Expose Shell constructor
this.Shell = Shell.bind(undefined, this); this.Shell = Shell.bind(undefined, this);
// Safely expose the operation queue // Safely expose the operation queue
var queue = []; let queue = [];
this.queueOrRun = function(operation) { this.queueOrRun = function (operation) {
var error; let error;
if(FS_READY === fs.readyState) { if (FS_READY === fs.readyState) {
operation.call(fs); operation.call(fs);
} else if(FS_ERROR === fs.readyState) { } else if (FS_ERROR === fs.readyState) {
error = new Errors.EFILESYSTEMERROR('unknown error'); error = new Errors.EFILESYSTEMERROR('unknown error');
} else { } else {
queue.push(operation); queue.push(operation);
@ -176,25 +181,25 @@ function FileSystem(options, callback) {
return error; return error;
}; };
function runQueued() { function runQueued() {
queue.forEach(function(operation) { queue.forEach(function (operation) {
operation.call(this); operation.call(this);
}.bind(fs)); }.bind(fs));
queue = null; queue = null;
} }
// We support the optional `options` arg from node, but ignore it // We support the optional `options` arg from node, but ignore it
this.watch = function(filename, options, listener) { this.watch = function (filename, options, listener) {
if(Path.isNull(filename)) { if (Path.isNull(filename)) {
throw new Error('Path must be a string without null bytes.'); throw new Error('Path must be a string without null bytes.');
} }
if(typeof options === 'function') { if (typeof options === 'function') {
listener = options; listener = options;
options = {}; options = {};
} }
options = options || {}; options = options || {};
listener = listener || nop; listener = listener || nop;
var watcher = new FSWatcher(); const watcher = new FSWatcher();
watcher.start(filename, false, options.recursive); watcher.start(filename, false, options.recursive);
watcher.on('change', listener); watcher.on('change', listener);
@ -203,24 +208,24 @@ function FileSystem(options, callback) {
// Deal with various approaches to node ID creation // Deal with various approaches to node ID creation
function wrappedGuidFn(context) { function wrappedGuidFn(context) {
return function(callback) { return function (callback) {
// Skip the duplicate ID check if asked to // Skip the duplicate ID check if asked to
if(flags.includes(FS_NODUPEIDCHECK)) { if (flags.includes(FS_NODUPEIDCHECK)) {
callback(null, guid()); callback(null, guid());
return; return;
} }
// Otherwise (default) make sure this id is unused first // Otherwise (default) make sure this id is unused first
function guidWithCheck(callback) { function guidWithCheck(callback) {
var id = guid(); const id = guid();
context.getObject(id, function(err, value) { context.getObject(id, function (err, value) {
if(err) { if (err) {
callback(err); callback(err);
return; return;
} }
// If this id is unused, use it, otherwise find another // If this id is unused, use it, otherwise find another
if(!value) { if (!value) {
callback(null, id); callback(null, id);
} else { } else {
guidWithCheck(callback); guidWithCheck(callback);
@ -234,28 +239,28 @@ function FileSystem(options, callback) {
// Let other instances (in this or other windows) know about // Let other instances (in this or other windows) know about
// any changes to this fs instance. // any changes to this fs instance.
function broadcastChanges(changes) { function broadcastChanges(changes) {
if(!changes.length) { if (!changes.length) {
return; return;
} }
var intercom = Intercom.getInstance(); const intercom = Intercom.getInstance();
changes.forEach(function(change) { changes.forEach(function (change) {
intercom.emit(change.event, change.path); intercom.emit(change.event, change.path);
}); });
} }
// Open file system storage provider // Open file system storage provider
provider.open(function(err) { provider.open(function (err) {
function complete(error) { function complete(error) {
function wrappedContext(methodName) { function wrappedContext(methodName) {
var context = provider[methodName](); let context = provider[methodName]();
context.name = name; context.name = name;
context.flags = flags; context.flags = flags;
context.changes = []; context.changes = [];
context.guid = wrappedGuidFn(context); context.guid = wrappedGuidFn(context);
// When the context is finished, let the fs deal with any change events // When the context is finished, let the fs deal with any change events
context.close = function() { context.close = function () {
var changes = context.changes; let changes = context.changes;
broadcastChanges(changes); broadcastChanges(changes);
changes.length = 0; changes.length = 0;
}; };
@ -268,15 +273,15 @@ function FileSystem(options, callback) {
// for paths updated during the lifetime of the context). From this // for paths updated during the lifetime of the context). From this
// point forward we won't call open again, so it's safe to drop it. // point forward we won't call open again, so it's safe to drop it.
fs.provider = { fs.provider = {
openReadWriteContext: function() { openReadWriteContext: function () {
return wrappedContext('getReadWriteContext'); return wrappedContext('getReadWriteContext');
}, },
openReadOnlyContext: function() { openReadOnlyContext: function () {
return wrappedContext('getReadOnlyContext'); return wrappedContext('getReadOnlyContext');
} }
}; };
if(error) { if (error) {
fs.readyState = FS_ERROR; fs.readyState = FS_ERROR;
} else { } else {
fs.readyState = FS_READY; fs.readyState = FS_READY;
@ -285,18 +290,18 @@ function FileSystem(options, callback) {
callback(error, fs); callback(error, fs);
} }
if(err) { if (err) {
return complete(err); return complete(err);
} }
var context = provider.getReadWriteContext(); const context = provider.getReadWriteContext();
context.guid = wrappedGuidFn(context); context.guid = wrappedGuidFn(context);
// Mount the filesystem, formatting if necessary // Mount the filesystem, formatting if necessary
if(forceFormatting) { if (forceFormatting) {
// Wipe the storage provider, then write root block // Wipe the storage provider, then write root block
context.clear(function(err) { context.clear(function (err) {
if(err) { if (err) {
return complete(err); return complete(err);
} }
impl.ensureRootDirectory(context, complete); impl.ensureRootDirectory(context, complete);
@ -317,13 +322,13 @@ function FileSystem(options, callback) {
* can be processed and validated before being passed on to the method. * can be processed and validated before being passed on to the method.
*/ */
[ [
{ name: 'appendFile', promises: true, absPathArgs: [ 0 ] }, { name: 'appendFile', promises: true, absPathArgs: [0] },
{ name: 'access', promises: true, absPathArgs: [ 0 ] }, { name: 'access', promises: true, absPathArgs: [0] },
{ name: 'chown', promises: true, absPathArgs: [ 0 ] }, { name: 'chown', promises: true, absPathArgs: [0] },
{ name: 'chmod', promises: true, absPathArgs: [ 0 ] }, { name: 'chmod', promises: true, absPathArgs: [0] },
{ name: 'close' }, { name: 'close' },
// copyFile - https://github.com/filerjs/filer/issues/436 // copyFile - https://github.com/filerjs/filer/issues/436
{ name: 'exists', absPathArgs: [ 0 ] }, { name: 'exists', absPathArgs: [0] },
{ name: 'fchown' }, { name: 'fchown' },
{ name: 'fchmod' }, { name: 'fchmod' },
// fdatasync - https://github.com/filerjs/filer/issues/653 // fdatasync - https://github.com/filerjs/filer/issues/653
@ -334,64 +339,64 @@ function FileSystem(options, callback) {
{ name: 'fsync' }, { name: 'fsync' },
{ name: 'ftruncate' }, { name: 'ftruncate' },
{ name: 'futimes' }, { name: 'futimes' },
{ name: 'getxattr', promises: true, absPathArgs: [ 0 ] }, { name: 'getxattr', promises: true, absPathArgs: [0] },
// lchown - https://github.com/filerjs/filer/issues/620 // lchown - https://github.com/filerjs/filer/issues/620
// lchmod - https://github.com/filerjs/filer/issues/619 // lchmod - https://github.com/filerjs/filer/issues/619
{ name: 'link', promises: true, absPathArgs: [0, 1] }, { name: 'link', promises: true, absPathArgs: [0, 1] },
{ name: 'lseek' }, { name: 'lseek' },
{ name: 'lstat', promises: true }, { name: 'lstat', promises: true },
{ name: 'mkdir', promises: true, absPathArgs: [ 0 ] }, { name: 'mkdir', promises: true, absPathArgs: [0] },
{ name: 'mkdtemp', promises: true }, { name: 'mkdtemp', promises: true },
{ name: 'mknod', promises: true, absPathArgs: [ 0 ] }, { name: 'mknod', promises: true, absPathArgs: [0] },
{ name: 'open', promises: true, absPathArgs: [ 0 ] }, { name: 'open', promises: true, absPathArgs: [0] },
{ name: 'readdir', promises: true, absPathArgs: [ 0 ] }, { name: 'readdir', promises: true, absPathArgs: [0] },
{ name: 'read' }, { name: 'read' },
{ name: 'readFile', promises: true, absPathArgs: [ 0 ] }, { name: 'readFile', promises: true, absPathArgs: [0] },
{ name: 'readlink', promises: true, absPathArgs: [ 0 ] }, { name: 'readlink', promises: true, absPathArgs: [0] },
// realpath - https://github.com/filerjs/filer/issues/85 // realpath - https://github.com/filerjs/filer/issues/85
{ name: 'removexattr', promises: true, absPathArgs: [ 0 ] }, { name: 'removexattr', promises: true, absPathArgs: [0] },
{ name: 'rename', promises: true, absPathArgs: [0, 1] }, { name: 'rename', promises: true, absPathArgs: [0, 1] },
{ name: 'rmdir', promises: true, absPathArgs: [ 0 ] }, { name: 'rmdir', promises: true, absPathArgs: [0] },
{ name: 'setxattr', promises: true, absPathArgs: [ 0 ] }, { name: 'setxattr', promises: true, absPathArgs: [0] },
{ name: 'stat', promises: true, absPathArgs: [ 0 ] }, { name: 'stat', promises: true, absPathArgs: [0] },
{ name: 'symlink', promises: true, relPathArgs: [ 0 ], absPathArgs: [ 1 ] }, { name: 'symlink', promises: true, relPathArgs: [0], absPathArgs: [1] },
{ name: 'truncate', promises: true, absPathArgs: [ 0 ] }, { name: 'truncate', promises: true, absPathArgs: [0] },
// unwatchFile - https://github.com/filerjs/filer/pull/553 // unwatchFile - https://github.com/filerjs/filer/pull/553
{ name: 'unlink', promises: true, absPathArgs: [ 0 ] }, { name: 'unlink', promises: true, absPathArgs: [0] },
{ name: 'utimes', promises: true, absPathArgs: [ 0 ] }, { name: 'utimes', promises: true, absPathArgs: [0] },
// watch - implemented above in `this.watch` // watch - implemented above in `this.watch`
// watchFile - https://github.com/filerjs/filer/issues/654 // watchFile - https://github.com/filerjs/filer/issues/654
{ name: 'writeFile', promises: true, absPathArgs: [ 0 ] }, { name: 'writeFile', promises: true, absPathArgs: [0] },
{ name: 'write' } { name: 'write' }
].forEach(function(method) { ].forEach(function (method) {
var methodName = method.name; const methodName = method.name;
var shouldPromisify = method.promises === true; const shouldPromisify = method.promises === true;
FileSystem.prototype[methodName] = function() { FileSystem.prototype[methodName] = function () {
var fs = this; const fs = this;
var args = Array.prototype.slice.call(arguments, 0); const args = Array.prototype.slice.call(arguments, 0);
var lastArgIndex = args.length - 1; const lastArgIndex = args.length - 1;
// We may or may not get a callback, and since node.js supports // We may or may not get a callback, and since node.js supports
// fire-and-forget style fs operations, we have to dance a bit here. // fire-and-forget style fs operations, we have to dance a bit here.
var missingCallback = typeof args[lastArgIndex] !== 'function'; const missingCallback = typeof args[lastArgIndex] !== 'function';
var callback = maybeCallback(args[lastArgIndex]); const callback = maybeCallback(args[lastArgIndex]);
// Deal with path arguments, validating and normalizing Buffer and file:// URLs // Deal with path arguments, validating and normalizing Buffer and file:// URLs
if(method.absPathArgs) { if (method.absPathArgs) {
method.absPathArgs.forEach(pathArg => processPathArg(args, pathArg, false)); method.absPathArgs.forEach(pathArg => processPathArg(args, pathArg, false));
} }
if(method.relPathArgs) { if (method.relPathArgs) {
method.relPathArgs.forEach(pathArg => processPathArg(args, pathArg, true)); method.relPathArgs.forEach(pathArg => processPathArg(args, pathArg, true));
} }
var error = fs.queueOrRun(function() { const error = fs.queueOrRun(function () {
var context = fs.provider.openReadWriteContext(); const context = fs.provider.openReadWriteContext();
// Fail early if the filesystem is in an error state (e.g., // Fail early if the filesystem is in an error state (e.g.,
// provider failed to open. // provider failed to open.
if(FS_ERROR === fs.readyState) { if (FS_ERROR === fs.readyState) {
var err = new Errors.EFILESYSTEMERROR('filesystem unavailable, operation canceled'); const err = new Errors.EFILESYSTEMERROR('filesystem unavailable, operation canceled');
return callback.call(fs, err); return callback.call(fs, err);
} }
@ -402,7 +407,7 @@ function FileSystem(options, callback) {
} }
// Either add or replace the callback with our wrapper complete() // Either add or replace the callback with our wrapper complete()
if(missingCallback) { if (missingCallback) {
args.push(complete); args.push(complete);
} else { } else {
args[lastArgIndex] = complete; args[lastArgIndex] = complete;
@ -411,16 +416,16 @@ function FileSystem(options, callback) {
// Forward this call to the impl's version, using the following // Forward this call to the impl's version, using the following
// call signature, with complete() as the callback/last-arg now: // call signature, with complete() as the callback/last-arg now:
// fn(fs, context, arg0, arg1, ... , complete); // fn(fs, context, arg0, arg1, ... , complete);
var fnArgs = [context].concat(args); const fnArgs = [context].concat(args);
impl[methodName].apply(null, fnArgs); impl[methodName].apply(null, fnArgs);
}); });
if(error) { if (error) {
callback(error); callback(error);
} }
}; };
// Add to fs.promises if appropriate // Add to fs.promises if appropriate
if(shouldPromisify) { if (shouldPromisify) {
FileSystem.prototype.promises[methodName] = promisify(FileSystem.prototype[methodName].bind(fs)); FileSystem.prototype.promises[methodName] = promisify(FileSystem.prototype[methodName].bind(fs));
} }
}); });