Comparing version 1.1.0 to 1.1.1
@@ -8,9 +8,8 @@ { | ||
"file", | ||
"system", | ||
"filesystem", | ||
"browser", | ||
"indexeddb", | ||
"idb", | ||
"websql" | ||
"idb" | ||
], | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"author": "Alan K <ack@modeswitch.org> (http://blog.modeswitch.org)", | ||
@@ -57,2 +56,3 @@ "homepage": "http://filerjs.github.io/filer", | ||
"eslint": "^5.10.0", | ||
"fake-indexeddb": "^2.0.4", | ||
"karma": "^3.1.4", | ||
@@ -59,0 +59,0 @@ "karma-chai": "^0.1.0", |
@@ -32,3 +32,2 @@ var Path = require('../path.js'); | ||
var Encoding = require('../encoding.js'); | ||
var Errors = require('../errors.js'); | ||
@@ -1831,3 +1830,3 @@ var DirectoryEntry = require('../directory-entry.js'); | ||
if(options.encoding === 'utf8') { | ||
data = Encoding.decode(buffer); | ||
data = buffer.toString('utf8'); | ||
} else { | ||
@@ -1873,3 +1872,3 @@ data = buffer; | ||
if(typeof data === 'string' && options.encoding === 'utf8') { | ||
data = Encoding.encode(data); | ||
data = Buffer.from(data); | ||
} | ||
@@ -1909,3 +1908,3 @@ | ||
if(typeof data === 'string' && options.encoding === 'utf8') { | ||
data = Encoding.encode(data); | ||
data = Buffer.from(data); | ||
} | ||
@@ -2168,3 +2167,3 @@ | ||
if (typeof time === 'object' && typeof time.getTime === 'function') { | ||
return time.getTime() / 1000; | ||
return time.getTime(); | ||
} | ||
@@ -2171,0 +2170,0 @@ } |
@@ -1,36 +0,41 @@ | ||
var { promisify } = require('es6-promisify'); | ||
'use strict'; | ||
var Path = require('../path.js'); | ||
var nop = require('../shared.js').nop; | ||
const { promisify } = require('es6-promisify'); | ||
var Constants = require('../constants.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; | ||
const Path = require('../path.js'); | ||
var providers = require('../providers/index.js'); | ||
const providers = require('../providers/index.js'); | ||
var Shell = require('../shell/shell.js'); | ||
var Intercom = require('../../lib/intercom.js'); | ||
var FSWatcher = require('../fs-watcher.js'); | ||
var Errors = require('../errors.js'); | ||
var defaultGuidFn = require('../shared.js').guid; | ||
const Shell = require('../shell/shell.js'); | ||
const Intercom = require('../../lib/intercom.js'); | ||
const FSWatcher = require('../fs-watcher.js'); | ||
const Errors = require('../errors.js'); | ||
const { | ||
nop, | ||
guid: defaultGuidFn | ||
} = require('../shared.js'); | ||
var STDIN = Constants.STDIN; | ||
var STDOUT = Constants.STDOUT; | ||
var STDERR = Constants.STDERR; | ||
const { | ||
fsConstants, | ||
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 | ||
var impl = require('./implementation.js'); | ||
const impl = require('./implementation.js'); | ||
// node.js supports a calling pattern that leaves off a callback. | ||
function maybeCallback(callback) { | ||
if(typeof callback === 'function') { | ||
if (typeof callback === 'function') { | ||
return callback; | ||
} | ||
return function(err) { | ||
if(err) { | ||
return function (err) { | ||
if (err) { | ||
throw err; | ||
@@ -43,3 +48,3 @@ } | ||
function defaultCallback(err) { | ||
if(err) { | ||
if (err) { | ||
/* eslint no-console: 0 */ | ||
@@ -52,16 +57,16 @@ console.error('Filer error: ', err); | ||
function toPathIfFileURL(fileURLOrPath) { | ||
if(!(fileURLOrPath && | ||
fileURLOrPath.protocol && | ||
fileURLOrPath.pathname)) { | ||
if (!(fileURLOrPath && | ||
fileURLOrPath.protocol && | ||
fileURLOrPath.pathname)) { | ||
return fileURLOrPath; | ||
} | ||
if(fileURLOrPath.protocol !== 'file:') { | ||
if (fileURLOrPath.protocol !== 'file:') { | ||
throw new Errors.EINVAL('only file: URLs are supported for paths', fileURLOrPath); | ||
} | ||
var pathname = fileURLOrPath.pathname; | ||
for (var n = 0; n < pathname.length; n++) { | ||
const pathname = fileURLOrPath.pathname; | ||
for (let n = 0; n < pathname.length; 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) { | ||
@@ -82,7 +87,7 @@ throw new Errors.EINVAL('file: URLs must not include encoded / characters', fileURLOrPath); | ||
function validatePath(path, allowRelative) { | ||
if(!path) { | ||
if (!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); | ||
} else if(!allowRelative && !Path.isAbsolute(path)) { | ||
} else if (!allowRelative && !Path.isAbsolute(path)) { | ||
return new Errors.EINVAL('Path must be absolute.', path); | ||
@@ -93,3 +98,3 @@ } | ||
function processPathArg(args, idx, allowRelative) { | ||
var path = args[idx]; | ||
let path = args[idx]; | ||
path = toPathIfFileURL(path); | ||
@@ -99,4 +104,4 @@ path = toPathIfBuffer(path); | ||
// Some methods specifically allow for rel paths (eg symlink with srcPath) | ||
var err = validatePath(path, allowRelative); | ||
if(err) { | ||
let err = validatePath(path, allowRelative); | ||
if (err) { | ||
throw err; | ||
@@ -141,10 +146,10 @@ } | ||
var flags = options.flags || []; | ||
var guid = options.guid ? options.guid : defaultGuidFn; | ||
var provider = options.provider || new providers.Default(options.name || FILE_SYSTEM_NAME); | ||
const flags = options.flags || []; | ||
const guid = options.guid ? options.guid : defaultGuidFn; | ||
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 | ||
var name = options.name || provider.name; | ||
var forceFormatting = flags.includes(FS_FORMAT); | ||
const name = options.name || provider.name; | ||
const forceFormatting = flags.includes(FS_FORMAT); | ||
var fs = this; | ||
const fs = this; | ||
fs.readyState = FS_PENDING; | ||
@@ -159,8 +164,8 @@ fs.name = name; | ||
// Expose Node's fs.constants to users | ||
fs.constants = Constants.fsConstants; | ||
fs.constants = fsConstants; | ||
// Node also forwards the access mode flags onto fs | ||
fs.F_OK = Constants.fsConstants.F_OK; | ||
fs.R_OK = Constants.fsConstants.R_OK; | ||
fs.W_OK = Constants.fsConstants.W_OK; | ||
fs.X_OK = Constants.fsConstants.X_OK; | ||
fs.F_OK = fsConstants.F_OK; | ||
fs.R_OK = fsConstants.R_OK; | ||
fs.W_OK = fsConstants.W_OK; | ||
fs.X_OK = fsConstants.X_OK; | ||
@@ -171,9 +176,9 @@ // Expose Shell constructor | ||
// Safely expose the operation queue | ||
var queue = []; | ||
this.queueOrRun = function(operation) { | ||
var error; | ||
let queue = []; | ||
this.queueOrRun = function (operation) { | ||
let error; | ||
if(FS_READY === fs.readyState) { | ||
if (FS_READY === fs.readyState) { | ||
operation.call(fs); | ||
} else if(FS_ERROR === fs.readyState) { | ||
} else if (FS_ERROR === fs.readyState) { | ||
error = new Errors.EFILESYSTEMERROR('unknown error'); | ||
@@ -187,3 +192,3 @@ } else { | ||
function runQueued() { | ||
queue.forEach(function(operation) { | ||
queue.forEach(function (operation) { | ||
operation.call(this); | ||
@@ -195,7 +200,7 @@ }.bind(fs)); | ||
// We support the optional `options` arg from node, but ignore it | ||
this.watch = function(filename, options, listener) { | ||
if(Path.isNull(filename)) { | ||
this.watch = function (filename, options, listener) { | ||
if (Path.isNull(filename)) { | ||
throw new Error('Path must be a string without null bytes.'); | ||
} | ||
if(typeof options === 'function') { | ||
if (typeof options === 'function') { | ||
listener = options; | ||
@@ -207,3 +212,3 @@ options = {}; | ||
var watcher = new FSWatcher(); | ||
const watcher = new FSWatcher(); | ||
watcher.start(filename, false, options.recursive); | ||
@@ -217,5 +222,5 @@ watcher.on('change', listener); | ||
function wrappedGuidFn(context) { | ||
return function(callback) { | ||
return function (callback) { | ||
// Skip the duplicate ID check if asked to | ||
if(flags.includes(FS_NODUPEIDCHECK)) { | ||
if (flags.includes(FS_NODUPEIDCHECK)) { | ||
callback(null, guid()); | ||
@@ -227,5 +232,5 @@ return; | ||
function guidWithCheck(callback) { | ||
var id = guid(); | ||
context.getObject(id, function(err, value) { | ||
if(err) { | ||
const id = guid(); | ||
context.getObject(id, function (err, value) { | ||
if (err) { | ||
callback(err); | ||
@@ -236,3 +241,3 @@ return; | ||
// If this id is unused, use it, otherwise find another | ||
if(!value) { | ||
if (!value) { | ||
callback(null, id); | ||
@@ -251,7 +256,7 @@ } else { | ||
function broadcastChanges(changes) { | ||
if(!changes.length) { | ||
if (!changes.length) { | ||
return; | ||
} | ||
var intercom = Intercom.getInstance(); | ||
changes.forEach(function(change) { | ||
const intercom = Intercom.getInstance(); | ||
changes.forEach(function (change) { | ||
intercom.emit(change.event, change.path); | ||
@@ -262,6 +267,6 @@ }); | ||
// Open file system storage provider | ||
provider.open(function(err) { | ||
provider.open(function (err) { | ||
function complete(error) { | ||
function wrappedContext(methodName) { | ||
var context = provider[methodName](); | ||
let context = provider[methodName](); | ||
context.name = name; | ||
@@ -273,4 +278,4 @@ context.flags = flags; | ||
// When the context is finished, let the fs deal with any change events | ||
context.close = function() { | ||
var changes = context.changes; | ||
context.close = function () { | ||
let changes = context.changes; | ||
broadcastChanges(changes); | ||
@@ -288,6 +293,6 @@ changes.length = 0; | ||
fs.provider = { | ||
openReadWriteContext: function() { | ||
openReadWriteContext: function () { | ||
return wrappedContext('getReadWriteContext'); | ||
}, | ||
openReadOnlyContext: function() { | ||
openReadOnlyContext: function () { | ||
return wrappedContext('getReadOnlyContext'); | ||
@@ -297,3 +302,3 @@ } | ||
if(error) { | ||
if (error) { | ||
fs.readyState = FS_ERROR; | ||
@@ -307,14 +312,14 @@ } else { | ||
if(err) { | ||
if (err) { | ||
return complete(err); | ||
} | ||
var context = provider.getReadWriteContext(); | ||
const context = provider.getReadWriteContext(); | ||
context.guid = wrappedGuidFn(context); | ||
// Mount the filesystem, formatting if necessary | ||
if(forceFormatting) { | ||
if (forceFormatting) { | ||
// Wipe the storage provider, then write root block | ||
context.clear(function(err) { | ||
if(err) { | ||
context.clear(function (err) { | ||
if (err) { | ||
return complete(err); | ||
@@ -340,9 +345,9 @@ } | ||
[ | ||
{ name: 'appendFile', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'access', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'chown', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'chmod', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'appendFile', promises: true, absPathArgs: [0] }, | ||
{ name: 'access', promises: true, absPathArgs: [0] }, | ||
{ name: 'chown', promises: true, absPathArgs: [0] }, | ||
{ name: 'chmod', promises: true, absPathArgs: [0] }, | ||
{ name: 'close' }, | ||
// copyFile - https://github.com/filerjs/filer/issues/436 | ||
{ name: 'exists', absPathArgs: [ 0 ] }, | ||
{ name: 'exists', absPathArgs: [0] }, | ||
{ name: 'fchown' }, | ||
@@ -358,3 +363,3 @@ { name: 'fchmod' }, | ||
{ name: 'futimes' }, | ||
{ name: 'getxattr', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'getxattr', promises: true, absPathArgs: [0] }, | ||
// lchown - https://github.com/filerjs/filer/issues/620 | ||
@@ -365,54 +370,54 @@ // lchmod - https://github.com/filerjs/filer/issues/619 | ||
{ name: 'lstat', promises: true }, | ||
{ name: 'mkdir', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'mkdir', promises: true, absPathArgs: [0] }, | ||
{ name: 'mkdtemp', promises: true }, | ||
{ name: 'mknod', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'open', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'readdir', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'mknod', promises: true, absPathArgs: [0] }, | ||
{ name: 'open', promises: true, absPathArgs: [0] }, | ||
{ name: 'readdir', promises: true, absPathArgs: [0] }, | ||
{ name: 'read' }, | ||
{ name: 'readFile', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'readlink', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'readFile', promises: true, absPathArgs: [0] }, | ||
{ name: 'readlink', promises: true, absPathArgs: [0] }, | ||
// 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: 'rmdir', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'setxattr', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'stat', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'symlink', promises: true, relPathArgs: [ 0 ], absPathArgs: [ 1 ] }, | ||
{ name: 'truncate', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'rmdir', promises: true, absPathArgs: [0] }, | ||
{ name: 'setxattr', promises: true, absPathArgs: [0] }, | ||
{ name: 'stat', promises: true, absPathArgs: [0] }, | ||
{ name: 'symlink', promises: true, relPathArgs: [0], absPathArgs: [1] }, | ||
{ name: 'truncate', promises: true, absPathArgs: [0] }, | ||
// unwatchFile - https://github.com/filerjs/filer/pull/553 | ||
{ name: 'unlink', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'utimes', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'unlink', promises: true, absPathArgs: [0] }, | ||
{ name: 'utimes', promises: true, absPathArgs: [0] }, | ||
// watch - implemented above in `this.watch` | ||
// watchFile - https://github.com/filerjs/filer/issues/654 | ||
{ name: 'writeFile', promises: true, absPathArgs: [ 0 ] }, | ||
{ name: 'writeFile', promises: true, absPathArgs: [0] }, | ||
{ name: 'write' } | ||
].forEach(function(method) { | ||
var methodName = method.name; | ||
var shouldPromisify = method.promises === true; | ||
].forEach(function (method) { | ||
const methodName = method.name; | ||
const shouldPromisify = method.promises === true; | ||
FileSystem.prototype[methodName] = function() { | ||
var fs = this; | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
var lastArgIndex = args.length - 1; | ||
FileSystem.prototype[methodName] = function () { | ||
const fs = this; | ||
const args = Array.prototype.slice.call(arguments, 0); | ||
const lastArgIndex = args.length - 1; | ||
// 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. | ||
var missingCallback = typeof args[lastArgIndex] !== 'function'; | ||
var callback = maybeCallback(args[lastArgIndex]); | ||
const missingCallback = typeof args[lastArgIndex] !== 'function'; | ||
const callback = maybeCallback(args[lastArgIndex]); | ||
// 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)); | ||
} | ||
if(method.relPathArgs) { | ||
if (method.relPathArgs) { | ||
method.relPathArgs.forEach(pathArg => processPathArg(args, pathArg, true)); | ||
} | ||
var error = fs.queueOrRun(function() { | ||
var context = fs.provider.openReadWriteContext(); | ||
const error = fs.queueOrRun(function () { | ||
const context = fs.provider.openReadWriteContext(); | ||
// Fail early if the filesystem is in an error state (e.g., | ||
// provider failed to open. | ||
if(FS_ERROR === fs.readyState) { | ||
var err = new Errors.EFILESYSTEMERROR('filesystem unavailable, operation canceled'); | ||
if (FS_ERROR === fs.readyState) { | ||
const err = new Errors.EFILESYSTEMERROR('filesystem unavailable, operation canceled'); | ||
return callback.call(fs, err); | ||
@@ -428,3 +433,3 @@ } | ||
// Either add or replace the callback with our wrapper complete() | ||
if(missingCallback) { | ||
if (missingCallback) { | ||
args.push(complete); | ||
@@ -438,12 +443,12 @@ } else { | ||
// fn(fs, context, arg0, arg1, ... , complete); | ||
var fnArgs = [context].concat(args); | ||
const fnArgs = [context].concat(args); | ||
impl[methodName].apply(null, fnArgs); | ||
}); | ||
if(error) { | ||
if (error) { | ||
callback(error); | ||
} | ||
}; | ||
// Add to fs.promises if appropriate | ||
if(shouldPromisify) { | ||
if (shouldPromisify) { | ||
FileSystem.prototype.promises[methodName] = promisify(FileSystem.prototype[methodName].bind(fs)); | ||
@@ -450,0 +455,0 @@ } |
@@ -1,5 +0,7 @@ | ||
var EventEmitter = require('../lib/eventemitter.js'); | ||
var Path = require('./path.js'); | ||
var Intercom = require('../lib/intercom.js'); | ||
'using strict'; | ||
const EventEmitter = require('../lib/eventemitter.js'); | ||
const Path = require('./path.js'); | ||
const Intercom = require('../lib/intercom.js'); | ||
/** | ||
@@ -11,6 +13,6 @@ * FSWatcher based on node.js' FSWatcher | ||
EventEmitter.call(this); | ||
var self = this; | ||
var recursive = false; | ||
var recursivePathPrefix; | ||
var filename; | ||
const self = this; | ||
let recursive = false; | ||
let recursivePathPrefix; | ||
let filename; | ||
@@ -50,3 +52,3 @@ function onchange(path) { | ||
var intercom = Intercom.getInstance(); | ||
const intercom = Intercom.getInstance(); | ||
intercom.on('change', onchange); | ||
@@ -56,3 +58,3 @@ }; | ||
self.close = function() { | ||
var intercom = Intercom.getInstance(); | ||
const intercom = Intercom.getInstance(); | ||
intercom.off('change', onchange); | ||
@@ -59,0 +61,0 @@ self.removeAllListeners('change'); |
@@ -6,7 +6,2 @@ var FILE_SYSTEM_NAME = require('../constants.js').FILE_SYSTEM_NAME; | ||
var indexedDB = global.indexedDB || | ||
global.mozIndexedDB || | ||
global.webkitIndexedDB || | ||
global.msIndexedDB; | ||
function IndexedDBContext(db, mode) { | ||
@@ -118,2 +113,6 @@ this.db = db; | ||
IndexedDB.isSupported = function() { | ||
var indexedDB = global.indexedDB || | ||
global.mozIndexedDB || | ||
global.webkitIndexedDB || | ||
global.msIndexedDB; | ||
return !!indexedDB; | ||
@@ -131,2 +130,7 @@ }; | ||
try { | ||
var indexedDB = global.indexedDB || | ||
global.mozIndexedDB || | ||
global.webkitIndexedDB || | ||
global.msIndexedDB; | ||
// NOTE: we're not using versioned databases. | ||
@@ -133,0 +137,0 @@ var openRequest = indexedDB.open(that.name); |
@@ -1,2 +0,3 @@ | ||
var defaults = require('../constants.js').ENVIRONMENT; | ||
'use strict'; | ||
const defaults = require('../constants.js').ENVIRONMENT; | ||
@@ -3,0 +4,0 @@ module.exports = function Environment(env) { |
@@ -1,7 +0,8 @@ | ||
var Constants = require('./constants.js'); | ||
var Path = require('./path.js'); | ||
'use strict'; | ||
// https://github.com/nodejs/node/blob/4f1297f259b09d129ac01afbd4c674263b7ac124/lib/internal/fs/utils.js#L231 | ||
function dateFromNumeric(num) { | ||
return new Date(Number(num) * 1000); | ||
const Constants = require('./constants.js'); | ||
const Path = require('./path.js'); | ||
function dateFromMs(ms) { | ||
return new Date(Number(ms)); | ||
} | ||
@@ -16,6 +17,6 @@ | ||
// Date objects | ||
this.atime = dateFromNumeric(fileNode.atime); | ||
this.mtime = dateFromNumeric(fileNode.mtime); | ||
this.ctime = dateFromNumeric(fileNode.ctime); | ||
// Unix timestamp Numbers | ||
this.atime = dateFromMs(fileNode.atime); | ||
this.mtime = dateFromMs(fileNode.mtime); | ||
this.ctime = dateFromMs(fileNode.ctime); | ||
// Unix timestamp MS Numbers | ||
this.atimeMs = fileNode.atime; | ||
@@ -22,0 +23,0 @@ this.mtimeMs = fileNode.mtime; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
1295326
20
29
12286