Socket
Socket
Sign inDemoInstall

fs-jetpack

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fs-jetpack - npm Package Compare versions

Comparing version 0.9.2 to 0.10.0

lib/utils/tree_walker.js

5

CHANGELOG.md

@@ -0,1 +1,6 @@

0.10.0 (2016-10-17)
-------------------
* `copyAsync()` uses only streams (much more memory efficient).
* `find()` supports `recursive` option.
0.9.2 (2016-06-27)

@@ -2,0 +7,0 @@ -------------------

129

lib/copy.js

@@ -11,3 +11,3 @@ 'use strict';

var fileMode = require('./utils/mode');
var inspectTree = require('./inspect_tree');
var treeWalker = require('./utils/tree_walker');
var write = require('./write');

@@ -81,3 +81,3 @@

var copyItemSync = function (inspectData, to) {
var copyItemSync = function (from, inspectData, to) {
var mode = fileMode.normalizeFileMode(inspectData.mode);

@@ -87,5 +87,5 @@ if (inspectData.type === 'dir') {

} else if (inspectData.type === 'file') {
copyFileSync(inspectData.absolutePath, to, mode);
copyFileSync(from, to, mode);
} else if (inspectData.type === 'symlink') {
copySymlinkSync(inspectData.absolutePath, to);
copySymlinkSync(from, to);
}

@@ -96,16 +96,17 @@ };

var opts = parseOptions(options, from);
var walker;
var inspectData;
var destPath;
checksBeforeCopyingSync(from, to, opts);
walker = inspectTree.createTreeWalkerSync(from);
while (walker.hasNext()) {
inspectData = walker.getNext();
destPath = pathUtil.join(to, inspectData.relativePath);
if (opts.allowedToCopy(inspectData.absolutePath)) {
copyItemSync(inspectData, destPath);
treeWalker.sync(from, {
inspectOptions: {
mode: true,
symlinks: true
}
}
}, function (path, inspectData) {
var rel = pathUtil.relative(from, path);
var destPath = pathUtil.resolve(to, rel);
if (opts.allowedToCopy(path)) {
copyItemSync(path, inspectData, destPath);
}
});
};

@@ -117,3 +118,2 @@

var promisedReadFile = Q.denodeify(fs.readFile);
var promisedSymlink = Q.denodeify(fs.symlink);

@@ -140,7 +140,24 @@ var promisedReadlink = Q.denodeify(fs.readlink);

var copyFileAsync = function (from, to, mode) {
return promisedReadFile(from)
.then(function (data) {
return write.async(to, data, { mode: mode });
});
var copyFileAsync = function (from, to, mode, retriedAttempt) {
var deferred = Q.defer();
fs.createReadStream(from)
.pipe(fs.createWriteStream(to, { mode: mode }))
.on('error', function (err) {
var toDirPath = pathUtil.dirname(to);
if (err.code === 'ENOENT' && retriedAttempt === undefined) {
// Some parent directory doesn't exits. Create it and retry.
promisedMkdirp(toDirPath).then(function () {
// Make retry attempt only once to prevent vicious infinite loop
// (when for some obscure reason I/O will keep returning ENOENT error).
// Passing retriedAttempt = true.
copyFileAsync(from, to, mode, true)
.then(deferred.resolve)
.catch(deferred.reject);
});
} else {
deferred.reject(err);
}
})
.on('finish', deferred.resolve);
return deferred.promise;
};

@@ -174,3 +191,3 @@

var copyItemAsync = function (inspectData, to) {
var copyItemAsync = function (from, inspectData, to) {
var mode = fileMode.normalizeFileMode(inspectData.mode);

@@ -180,5 +197,5 @@ if (inspectData.type === 'dir') {

} else if (inspectData.type === 'file') {
return copyFileAsync(inspectData.absolutePath, to, mode);
return copyFileAsync(from, to, mode);
} else if (inspectData.type === 'symlink') {
return copySymlinkAsync(inspectData.absolutePath, to);
return copySymlinkAsync(from, to);
}

@@ -190,30 +207,2 @@ // Ha! This is none of supported file system entities. What now?

var runCopyLoop = function (from, to, opts) {
var deferred = Q.defer();
var inspectData;
var destPath;
var copyNext = function (walker) {
if (walker.hasNext()) {
inspectData = walker.getNext();
destPath = pathUtil.join(to, inspectData.relativePath);
if (opts.allowedToCopy(inspectData.absolutePath)) {
copyItemAsync(inspectData, destPath)
.then(function () {
copyNext(walker);
})
.catch(deferred.reject);
} else {
copyNext(walker);
}
} else {
deferred.resolve();
}
};
inspectTree.createTreeWalkerAsync(from).then(copyNext);
return deferred.promise;
};
var copyAsync = function (from, to, options) {

@@ -225,5 +214,39 @@ var deferred = Q.defer();

.then(function () {
return runCopyLoop(from, to, opts);
var allFilesDelivered = false;
var filesInProgress = 0;
var stream = treeWalker.stream(from, {
inspectOptions: {
mode: true,
symlinks: true
}
})
.on('readable', function () {
var item = stream.read();
var rel;
var destPath;
if (item) {
rel = pathUtil.relative(from, item.path);
destPath = pathUtil.resolve(to, rel);
if (opts.allowedToCopy(item.path)) {
filesInProgress += 1;
copyItemAsync(item.path, item.item, destPath)
.then(function () {
filesInProgress -= 1;
if (allFilesDelivered && filesInProgress === 0) {
deferred.resolve();
}
})
.catch(deferred.reject);
}
}
})
.on('error', deferred.reject)
.on('end', function () {
allFilesDelivered = true;
if (allFilesDelivered && filesInProgress === 0) {
deferred.resolve();
}
});
})
.then(deferred.resolve)
.catch(deferred.reject);

@@ -230,0 +253,0 @@

@@ -5,3 +5,4 @@ 'use strict';

var Q = require('q');
var inspectTree = require('./inspect_tree');
var treeWalker = require('./utils/tree_walker');
var inspect = require('./inspect');
var matcher = require('./utils/matcher');

@@ -18,23 +19,8 @@

}
if (opts.recursive === undefined) {
opts.recursive = true;
}
return opts;
};
var filterTree = function (tree, options) {
var matchesAnyOfGlobs = matcher.create(options.matching, tree.absolutePath);
return inspectTree.utils.flattenTree(tree)
.filter(function (inspectObj) {
return matchesAnyOfGlobs(inspectObj.absolutePath);
})
.filter(function (inspectObj) {
if (inspectObj.type === 'file' && options.files === true) {
return true;
}
if (inspectObj.type === 'dir' && options.directories === true) {
return true;
}
return false;
});
};
var processFoundObjects = function (foundObjects, cwd) {

@@ -63,17 +49,31 @@ return foundObjects.map(function (inspectObj) {

var findSync = function (path, options) {
var foundInspectObjects;
var tree;
var foundInspectObjects = [];
var matchesAnyOfGlobs = matcher.create(options.matching, path);
tree = inspectTree.sync(path, {
absolutePath: true
treeWalker.sync(path, {
maxLevelsDeep: options.recursive ? Infinity : 1,
inspectOptions: {
absolutePath: true
}
}, function (itemPath, item) {
if (matchesAnyOfGlobs(itemPath)) {
if ((item.type === 'file' && options.files === true)
|| (item.type === 'dir' && options.directories === true)) {
foundInspectObjects.push(item);
}
}
});
if (tree === undefined) {
return processFoundObjects(foundInspectObjects, options.cwd);
};
var findSyncInit = function (path, options) {
var entryPointInspect = inspect.sync(path);
if (entryPointInspect === undefined) {
throw generatePathDoesntExistError(path);
} else if (tree.type !== 'dir') {
} else if (entryPointInspect.type !== 'dir') {
throw generatePathNotDirectoryError(path);
}
foundInspectObjects = filterTree(tree, normalizeOptions(options));
return processFoundObjects(foundInspectObjects, options.cwd);
return findSync(path, normalizeOptions(options));
};

@@ -87,22 +87,28 @@

var deferred = Q.defer();
var foundInspectObjects = [];
var matchesAnyOfGlobs = matcher.create(options.matching, path);
inspectTree.async(path, {
relativePath: true,
absolutePath: true
var walker = treeWalker.stream(path, {
maxLevelsDeep: options.recursive ? Infinity : 1,
inspectOptions: {
absolutePath: true
}
})
.then(function (tree) {
var foundInspectObjects;
var toReturn;
if (tree === undefined) {
throw generatePathDoesntExistError(path);
} else if (tree.type !== 'dir') {
throw generatePathNotDirectoryError(path);
.on('readable', function () {
var data = walker.read();
var item;
if (data) {
item = data.item;
if (matchesAnyOfGlobs(data.path)) {
if ((item.type === 'file' && options.files === true)
|| (item.type === 'dir' && options.directories === true)) {
foundInspectObjects.push(item);
}
}
}
foundInspectObjects = filterTree(tree, normalizeOptions(options));
toReturn = processFoundObjects(foundInspectObjects, options.cwd);
deferred.resolve(toReturn);
})
.catch(deferred.reject);
.on('error', deferred.reject)
.on('end', function () {
deferred.resolve(processFoundObjects(foundInspectObjects, options.cwd));
});

@@ -112,2 +118,14 @@ return deferred.promise;

var findAsyncInit = function (path, options) {
return inspect.async(path)
.then(function (entryPointInspect) {
if (entryPointInspect === undefined) {
throw generatePathDoesntExistError(path);
} else if (entryPointInspect.type !== 'dir') {
throw generatePathNotDirectoryError(path);
}
return findAsync(path, normalizeOptions(options));
});
};
// ---------------------------------------------------------

@@ -117,3 +135,3 @@ // API

exports.sync = findSync;
exports.async = findAsync;
exports.sync = findSyncInit;
exports.async = findAsyncInit;

@@ -26,18 +26,2 @@ 'use strict';

// Flattens tree structure to one list of inspectObjects.
var flattenTree = function (tree) {
var treeAsList = [];
var crawl = function (inspectObj) {
treeAsList.push(inspectObj);
if (inspectObj.children) {
inspectObj.children.forEach(crawl);
}
};
crawl(tree);
return treeAsList;
};
// ---------------------------------------------------------

@@ -81,18 +65,2 @@ // Sync

var createTreeWalkerSync = function (startPath) {
var allFiles = flattenTree(inspectTreeSync(startPath, {
absolutePath: true,
relativePath: true,
mode: true
}));
return {
hasNext: function () {
return allFiles.length > 0;
},
getNext: function () {
return allFiles.shift();
}
};
};
// ---------------------------------------------------------

@@ -171,25 +139,2 @@ // Async

var createTreeWalkerAsync = function (startPath) {
var deferred = Q.defer();
inspectTreeAsync(startPath, {
absolutePath: true,
relativePath: true,
mode: true
})
.then(function (wholeTree) {
var allFiles = flattenTree(wholeTree);
deferred.resolve({
hasNext: function () {
return allFiles.length > 0;
},
getNext: function () {
return allFiles.shift();
}
});
});
return deferred.promise;
};
// ---------------------------------------------------------

@@ -200,9 +145,2 @@ // API

exports.sync = inspectTreeSync;
exports.createTreeWalkerSync = createTreeWalkerSync;
exports.async = inspectTreeAsync;
exports.createTreeWalkerAsync = createTreeWalkerAsync;
exports.utils = {
flattenTree: flattenTree
};
{
"name": "fs-jetpack",
"description": "Better file system API",
"version": "0.9.2",
"version": "0.10.0",
"author": "Jakub Szwacz <jakub@szwacz.com>",

@@ -6,0 +6,0 @@ "dependencies": {

@@ -330,2 +330,3 @@ fs-jetpack [![Build Status](https://travis-ci.org/szwacz/fs-jetpack.svg?branch=master)](https://travis-ci.org/szwacz/fs-jetpack) [![Build status](https://ci.appveyor.com/api/projects/status/er206e91fpuuqf58?svg=true)](https://ci.appveyor.com/project/szwacz/fs-jetpack)

* `directories` (default `false`) whether or not should search for directories.
* `recursive` (default `true`) whether the whole directory tree should be searched recursively, or only one-level of given directory (excluding it's subdirectories).

@@ -332,0 +333,0 @@ **returns:**

@@ -32,2 +32,23 @@ /* eslint-env jasmine */

it('if recursive option set will exclude subfolders from search', function (done) {
var expectations = function (found) {
var normalizedFound = helper.convertToUnixPathSeparators(found);
expect(normalizedFound).toEqual(['x/file.txt']);
};
fse.outputFileSync('x/file.txt', 'abc');
fse.outputFileSync('x/y/file.txt', '123');
fse.outputFileSync('x/y/b/file.txt', '456');
// SYNC
expectations(jetpack.find('x', { matching: '*.txt', recursive: false }));
// ASYNC
jetpack.findAsync('x', { matching: '*.txt', recursive: false })
.then(function (found) {
expectations(found);
done();
});
});
it('defaults to CWD if no path provided', function (done) {

@@ -34,0 +55,0 @@ var expectations = function (found) {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc