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.12.0 to 0.13.0

benchmark/remove.js

81

benchmark/copy.js

@@ -1,3 +0,1 @@

// Benchmark to make sure performance of copy is near 'native' bash command.
/* eslint no-console: 0 */

@@ -7,10 +5,5 @@

var Q = require('q');
var os = require('os');
var childProcess = require('child_process');
var promisedExec = Q.denodeify(childProcess.exec);
var benchUtils = require('./utils');
var jetpack = require('..');
var utils = require('./utils');
var testDir = jetpack.dir(os.tmpdir() + '/jetpack-benchmark', { empty: true });
var testDir = utils.prepareJetpackTestDir();
var toCopyDir = testDir.dir('to-copy');

@@ -21,39 +14,9 @@ var timer;

var prepareFiles = function (testConfig) {
return new Q.Promise(function (resolve, reject) {
var count = 0;
var content = new Buffer(testConfig.size);
var makeOneFile = function () {
toCopyDir.fileAsync(count + '.txt', { content: content })
.then(function () {
count += 1;
if (count < testConfig.files) {
makeOneFile();
} else {
resolve();
}
}, reject);
};
console.log('Preparing ' + testConfig.files + ' test files (' +
benchUtils.humanFileSize(testConfig.size, true) + ' each)...');
makeOneFile();
});
};
var waitAWhile = function () {
return new Q.Promise(function (resolve) {
console.log('Waiting 10s to allow hardware buffers be emptied...');
setTimeout(resolve, 10000);
});
};
var test = function (testConfig) {
console.log('----------------------');
console.log('');
return prepareFiles(testConfig)
.then(waitAWhile)
return utils.prepareFiles(toCopyDir, testConfig)
.then(utils.waitAWhile)
.then(function () {
timer = benchUtils.startTimer('jetpack.copyAsync()');
timer = utils.startTimer('jetpack.copyAsync()');
return toCopyDir.copyAsync('.', testDir.path('copied-jetpack'));

@@ -63,14 +26,12 @@ })

jetpackTime = timer();
return waitAWhile();
return utils.waitAWhile();
})
.then(function () {
timer = benchUtils.startTimer('Native cp -R');
return promisedExec('cp -R ' + toCopyDir.path() + ' ' + testDir.path('copied-native'));
timer = utils.startTimer('Native cp -R');
return utils.exec('cp -R ' + toCopyDir.path() + ' ' + testDir.path('copied-native'));
})
.then(function () {
nativeTime = timer();
console.log('Jetpack is ' + (jetpackTime / nativeTime).toFixed(1) +
' times slower than native');
console.log('Cleaning up after test...');
return testDir.removeAsync();
utils.showDifferenceInfo(jetpackTime, nativeTime);
return utils.cleanAfterTest();
})

@@ -82,12 +43,12 @@ .catch(function (err) {

var testConfigs = [{
files: 10000,
size: 100
}, {
files: 1000,
size: 1000 * 100
}, {
files: 100,
size: 1000 * 1000 * 10
}];
var testConfigs = [
{
files: 10000,
size: 1000
},
{
files: 50,
size: 1000 * 1000 * 10
}
];

@@ -94,0 +55,0 @@ var runNext = function () {

@@ -5,13 +5,8 @@ /* eslint no-console:0 */

exports.startTimer = function (startMessage) {
var start = Date.now();
process.stdout.write(startMessage + ' ... ');
return function stop() {
var time = Date.now() - start;
console.log(time + 'ms');
return time;
};
};
var os = require('os');
var childProcess = require('child_process');
var promisify = require('../lib/utils/promisify');
var jetpack = require('..');
exports.humanFileSize = function (bytes, si) {
var humanReadableFileSize = function (bytes, si) {
var units;

@@ -34,1 +29,71 @@ var u;

};
var testDirPath = function () {
return os.tmpdir() + '/jetpack-benchmark';
};
var prepareJetpackTestDir = function () {
return jetpack.dir(testDirPath(), { empty: true });
};
var prepareFiles = function (jetpackDir, creationConfig) {
return new Promise(function (resolve, reject) {
var count = 0;
var content = new Buffer(creationConfig.size);
var makeOneFile = function () {
jetpackDir.fileAsync(count + '.txt', { content: content })
.then(function () {
count += 1;
if (count < creationConfig.files) {
makeOneFile();
} else {
resolve();
}
}, reject);
};
console.log('Preparing ' + creationConfig.files + ' test files (' +
humanReadableFileSize(creationConfig.size, true) + ' each)...');
makeOneFile();
});
};
var startTimer = function (startMessage) {
var start = Date.now();
process.stdout.write(startMessage + ' ... ');
return function stop() {
var time = Date.now() - start;
console.log(time + 'ms');
return time;
};
};
var waitAWhile = function () {
return new Promise(function (resolve) {
console.log('Waiting 5s to allow hardware buffers be emptied...');
setTimeout(resolve, 5000);
});
};
var promisedExec = promisify(childProcess.exec);
var showDifferenceInfo = function (jetpackTime, nativeTime) {
var perc = Math.round(jetpackTime / nativeTime * 100) - 100;
console.log('Jetpack is ' + perc + '% slower than native');
};
var cleanAfterTest = function () {
console.log('Cleaning up after test...');
return jetpack.removeAsync(testDirPath());
};
module.exports = {
prepareJetpackTestDir: prepareJetpackTestDir,
prepareFiles: prepareFiles,
startTimer: startTimer,
waitAWhile: waitAWhile,
exec: promisedExec,
showDifferenceInfo: showDifferenceInfo,
cleanAfterTest: cleanAfterTest
};

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

# 0.13.0 (2017-03-15)
- **(breaking change)** Dropped support for node.js 0.10 and 0.12
- **(possibly breaking change)** fs-jetpack no longer uses libraries `mkdirp` and `rimraf`, those have been replaced with in-house implementations doing the same task. The new implementations are simpler than original libraries, so some edge cases might emerge after upgrading (please file an issue if you stumbled upon such case).
- Started using native promises instead of `Q` library
# 0.12.0 (2017-02-19)

@@ -2,0 +7,0 @@ - **(breaking change)** Changes in `symlinks` option passed to `inspect()`.

'use strict';
var fs = require('fs');
var Q = require('q');
var fs = require('./utils/fs');
var write = require('./write');

@@ -39,20 +38,16 @@ var validate = require('./utils/validate');

var promisedAppendFile = Q.denodeify(fs.appendFile);
var appendAsync = function (path, data, options) {
var deferred = Q.defer();
promisedAppendFile(path, data, options)
.then(deferred.resolve)
.catch(function (err) {
if (err.code === 'ENOENT') {
// Parent directory doesn't exist, so just pass the task to `write`,
// which will create the folder and file.
write.async(path, data, options).then(deferred.resolve, deferred.reject);
} else {
deferred.reject(err);
}
return new Promise(function (resolve, reject) {
fs.appendFile(path, data, options)
.then(resolve)
.catch(function (err) {
if (err.code === 'ENOENT') {
// Parent directory doesn't exist, so just pass the task to `write`,
// which will create the folder and file.
write.async(path, data, options).then(resolve, reject);
} else {
reject(err);
}
});
});
return deferred.promise;
};

@@ -59,0 +54,0 @@

'use strict';
var pathUtil = require('path');
var fs = require('fs');
var Q = require('q');
var mkdirp = require('mkdirp');
var fs = require('./utils/fs');
var dir = require('./dir');
var exists = require('./exists');

@@ -94,3 +92,3 @@ var matcher = require('./utils/matcher');

if (inspectData.type === 'dir') {
mkdirp.sync(to, { mode: mode });
dir.createSync(to, { mode: mode });
} else if (inspectData.type === 'file') {

@@ -126,7 +124,2 @@ copyFileSync(from, to, mode);

var promisedSymlink = Q.denodeify(fs.symlink);
var promisedReadlink = Q.denodeify(fs.readlink);
var promisedUnlink = Q.denodeify(fs.unlink);
var promisedMkdirp = Q.denodeify(mkdirp);
var checksBeforeCopyingAsync = function (from, to, opts) {

@@ -149,61 +142,57 @@ return exists.async(from)

var copyFileAsync = function (from, to, mode, retriedAttempt) {
var deferred = Q.defer();
return new Promise(function (resolve, reject) {
var readStream = fs.createReadStream(from);
var writeStream = fs.createWriteStream(to, { mode: mode });
var readStream = fs.createReadStream(from);
var writeStream = fs.createWriteStream(to, { mode: mode });
readStream.on('error', reject);
readStream.on('error', deferred.reject);
writeStream.on('error', function (err) {
var toDirPath = pathUtil.dirname(to);
writeStream.on('error', function (err) {
var toDirPath = pathUtil.dirname(to);
// Force read stream to close, since write stream errored
// read stream serves us no purpose.
readStream.resume();
// Force read stream to close, since write stream errored
// read stream serves us no purpose.
readStream.resume();
if (err.code === 'ENOENT' && retriedAttempt === undefined) {
// Some parent directory doesn't exits. Create it and retry.
dir.createAsync(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(resolve)
.catch(reject);
});
} else {
reject(err);
}
});
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);
}
writeStream.on('finish', resolve);
readStream.pipe(writeStream);
});
writeStream.on('finish', deferred.resolve);
readStream.pipe(writeStream);
return deferred.promise;
};
var copySymlinkAsync = function (from, to) {
return promisedReadlink(from)
return fs.readlink(from)
.then(function (symlinkPointsAt) {
var deferred = Q.defer();
promisedSymlink(symlinkPointsAt, to)
.then(deferred.resolve)
.catch(function (err) {
if (err.code === 'EEXIST') {
// There is already file/symlink with this name on destination location.
// Must erase it manually, otherwise system won't allow us to place symlink there.
promisedUnlink(to)
.then(function () {
// Retry...
return promisedSymlink(symlinkPointsAt, to);
})
.then(deferred.resolve, deferred.reject);
} else {
deferred.reject(err);
}
return new Promise(function (resolve, reject) {
fs.symlink(symlinkPointsAt, to)
.then(resolve)
.catch(function (err) {
if (err.code === 'EEXIST') {
// There is already file/symlink with this name on destination location.
// Must erase it manually, otherwise system won't allow us to place symlink there.
fs.unlink(to)
.then(function () {
// Retry...
return fs.symlink(symlinkPointsAt, to);
})
.then(resolve, reject);
} else {
reject(err);
}
});
});
return deferred.promise;
});

@@ -215,3 +204,3 @@ };

if (inspectData.type === 'dir') {
return promisedMkdirp(to, { mode: mode });
return dir.createAsync(to, { mode: mode });
} else if (inspectData.type === 'file') {

@@ -224,51 +213,50 @@ return copyFileAsync(from, to, mode);

// Just continuing without actually copying sounds sane.
return new Q();
return Promise.resolve();
};
var copyAsync = function (from, to, options) {
var deferred = Q.defer();
var opts = parseOptions(options, from);
return new Promise(function (resolve, reject) {
var opts = parseOptions(options, from);
checksBeforeCopyingAsync(from, to, opts)
.then(function () {
var allFilesDelivered = false;
var filesInProgress = 0;
checksBeforeCopyingAsync(from, to, opts)
.then(function () {
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);
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) {
resolve();
}
})
.catch(reject);
}
}
})
.on('error', reject)
.on('end', function () {
allFilesDelivered = true;
if (allFilesDelivered && filesInProgress === 0) {
resolve();
}
});
})
.on('error', deferred.reject)
.on('end', function () {
allFilesDelivered = true;
if (allFilesDelivered && filesInProgress === 0) {
deferred.resolve();
}
});
})
.catch(deferred.reject);
return deferred.promise;
.catch(reject);
});
};

@@ -275,0 +263,0 @@

'use strict';
var pathUtil = require('path');
var fs = require('fs');
var Q = require('q');
var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var fs = require('./utils/fs');
var modeUtil = require('./utils/mode');
var validate = require('./utils/validate');
var remove = require('./remove');

@@ -60,4 +57,19 @@ var validateInput = function (methodName, path, criteria) {

var createBrandNewDirectorySync = function (path, criteria) {
mkdirp.sync(path, { mode: criteria.mode });
var createBrandNewDirectorySync = function (path, opts) {
var options = opts || {};
try {
fs.mkdirSync(path, options.mode);
} catch (err) {
if (err.code === 'ENOENT') {
// Parent directory doesn't exist. Need to create it first.
createBrandNewDirectorySync(pathUtil.dirname(path), options);
// Now retry creating this directory.
fs.mkdirSync(path, options.mode);
} else if (err.code === 'EEXIST') {
// The path already exists. We're fine.
} else {
throw err;
}
}
};

@@ -79,3 +91,3 @@

list.forEach(function (filename) {
rimraf.sync(pathUtil.resolve(path, filename));
remove.sync(pathUtil.resolve(path, filename));
});

@@ -103,30 +115,22 @@ }

var promisedStat = Q.denodeify(fs.stat);
var promisedChmod = Q.denodeify(fs.chmod);
var promisedReaddir = Q.denodeify(fs.readdir);
var promisedRimraf = Q.denodeify(rimraf);
var promisedMkdirp = Q.denodeify(mkdirp);
var checkWhatAlreadyOccupiesPathAsync = function (path) {
var deferred = Q.defer();
promisedStat(path)
.then(function (stat) {
if (stat.isDirectory()) {
deferred.resolve(stat);
} else {
deferred.reject(generatePathOccupiedByNotDirectoryError(path));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist
deferred.resolve(undefined);
} else {
// This is other error that nonexistent path, so end here.
deferred.reject(err);
}
return new Promise(function (resolve, reject) {
fs.stat(path)
.then(function (stat) {
if (stat.isDirectory()) {
resolve(stat);
} else {
reject(generatePathOccupiedByNotDirectoryError(path));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist
resolve(undefined);
} else {
// This is other error that nonexistent path, so end here.
reject(err);
}
});
});
return deferred.promise;
};

@@ -136,68 +140,84 @@

var emptyAsync = function (path) {
var deferred = Q.defer();
return new Promise(function (resolve, reject) {
fs.readdir(path)
.then(function (list) {
var doOne = function (index) {
var subPath;
if (index === list.length) {
resolve();
} else {
subPath = pathUtil.resolve(path, list[index]);
remove.async(subPath).then(function () {
doOne(index + 1);
});
}
};
promisedReaddir(path)
.then(function (list) {
var doOne = function (index) {
var subPath;
if (index === list.length) {
deferred.resolve();
} else {
subPath = pathUtil.resolve(path, list[index]);
promisedRimraf(subPath).then(function () {
doOne(index + 1);
});
doOne(0);
})
.catch(reject);
});
};
var checkExistingDirectoryFulfillsCriteriaAsync = function (path, stat, criteria) {
return new Promise(function (resolve, reject) {
var checkMode = function () {
var mode = modeUtil.normalizeFileMode(stat.mode);
if (criteria.mode !== undefined && criteria.mode !== mode) {
return fs.chmod(path, criteria.mode);
}
return Promise.resolve();
};
doOne(0);
})
.catch(deferred.reject);
var checkEmptiness = function () {
if (criteria.empty) {
return emptyAsync(path);
}
return Promise.resolve();
};
return deferred.promise;
checkMode()
.then(checkEmptiness)
.then(resolve, reject);
});
};
var checkExistingDirectoryFulfillsCriteriaAsync = function (path, stat, criteria) {
var deferred = Q.defer();
var createBrandNewDirectoryAsync = function (path, opts) {
var options = opts || {};
var checkMode = function () {
var mode = modeUtil.normalizeFileMode(stat.mode);
if (criteria.mode !== undefined && criteria.mode !== mode) {
return promisedChmod(path, criteria.mode);
}
return new Q();
};
var checkEmptiness = function () {
if (criteria.empty) {
return emptyAsync(path);
}
return new Q();
};
checkMode()
.then(checkEmptiness)
.then(deferred.resolve, deferred.reject);
return deferred.promise;
return new Promise(function (resolve, reject) {
fs.mkdir(path, options.mode)
.then(resolve)
.catch(function (err) {
if (err.code === 'ENOENT') {
// Parent directory doesn't exist. Need to create it first.
createBrandNewDirectoryAsync(pathUtil.dirname(path), options)
.then(function () {
// Now retry creating this directory.
return fs.mkdir(path, options.mode);
})
.then(resolve, reject);
} else if (err.code === 'EEXIST') {
// The path already exists. We're fine.
resolve();
} else {
reject(err);
}
});
});
};
var createBrandNewDirectoryAsync = function (path, criteria) {
return promisedMkdirp(path, { mode: criteria.mode });
};
var dirAsync = function (path, passedCriteria) {
var deferred = Q.defer();
var criteria = getCriteriaDefaults(passedCriteria);
return new Promise(function (resolve, reject) {
var criteria = getCriteriaDefaults(passedCriteria);
checkWhatAlreadyOccupiesPathAsync(path)
.then(function (stat) {
if (stat !== undefined) {
return checkExistingDirectoryFulfillsCriteriaAsync(path, stat, criteria);
}
return createBrandNewDirectoryAsync(path, criteria);
})
.then(deferred.resolve, deferred.reject);
return deferred.promise;
checkWhatAlreadyOccupiesPathAsync(path)
.then(function (stat) {
if (stat !== undefined) {
return checkExistingDirectoryFulfillsCriteriaAsync(path, stat, criteria);
}
return createBrandNewDirectoryAsync(path, criteria);
})
.then(resolve, reject);
});
};

@@ -209,4 +229,6 @@

module.exports.validateInput = validateInput;
module.exports.sync = dirSync;
module.exports.async = dirAsync;
exports.validateInput = validateInput;
exports.sync = dirSync;
exports.createSync = createBrandNewDirectorySync;
exports.async = dirAsync;
exports.createAsync = createBrandNewDirectoryAsync;
'use strict';
var fs = require('fs');
var Q = require('q');
var fs = require('./utils/fs');
var validate = require('./utils/validate');

@@ -40,21 +39,19 @@

var existsAsync = function (path) {
var deferred = Q.defer();
fs.stat(path, function (err, stat) {
if (err) {
if (err.code === 'ENOENT') {
deferred.resolve(false);
return new Promise(function (resolve, reject) {
fs.stat(path, function (err, stat) {
if (err) {
if (err.code === 'ENOENT') {
resolve(false);
} else {
reject(err);
}
} else if (stat.isDirectory()) {
resolve('dir');
} else if (stat.isFile()) {
resolve('file');
} else {
deferred.reject(err);
resolve('other');
}
} else if (stat.isDirectory()) {
deferred.resolve('dir');
} else if (stat.isFile()) {
deferred.resolve('file');
} else {
deferred.resolve('other');
}
});
});
return deferred.promise;
};

@@ -61,0 +58,0 @@

'use strict';
var fs = require('fs');
var Q = require('q');
var fs = require('./utils/fs');
var modeUtil = require('./utils/mode');

@@ -107,27 +105,22 @@ var validate = require('./utils/validate');

var promisedStat = Q.denodeify(fs.stat);
var promisedChmod = Q.denodeify(fs.chmod);
var checkWhatAlreadyOccupiesPathAsync = function (path) {
var deferred = Q.defer();
promisedStat(path)
.then(function (stat) {
if (stat.isFile()) {
deferred.resolve(stat);
} else {
deferred.reject(generatePathOccupiedByNotFileError(path));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist.
deferred.resolve(undefined);
} else {
// This is other error. Must end here.
deferred.reject(err);
}
return new Promise(function (resolve, reject) {
fs.stat(path)
.then(function (stat) {
if (stat.isFile()) {
resolve(stat);
} else {
reject(generatePathOccupiedByNotFileError(path));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Path doesn't exist.
resolve(undefined);
} else {
// This is other error. Must end here.
reject(err);
}
});
});
return deferred.promise;
};

@@ -139,18 +132,16 @@

var checkContent = function () {
var deferred = Q.defer();
if (criteria.content !== undefined) {
write.async(path, criteria.content, {
mode: mode,
jsonIndent: criteria.jsonIndent
})
.then(function () {
deferred.resolve(true);
})
.catch(deferred.reject);
} else {
deferred.resolve(false);
}
return deferred.promise;
return new Promise(function (resolve, reject) {
if (criteria.content !== undefined) {
write.async(path, criteria.content, {
mode: mode,
jsonIndent: criteria.jsonIndent
})
.then(function () {
resolve(true);
})
.catch(reject);
} else {
resolve(false);
}
});
};

@@ -160,3 +151,3 @@

if (criteria.mode !== undefined && criteria.mode !== mode) {
return promisedChmod(path, criteria.mode);
return fs.chmod(path, criteria.mode);
}

@@ -188,15 +179,14 @@ return undefined;

var fileAsync = function (path, passedCriteria) {
var deferred = Q.defer();
var criteria = getCriteriaDefaults(passedCriteria);
return new Promise(function (resolve, reject) {
var criteria = getCriteriaDefaults(passedCriteria);
checkWhatAlreadyOccupiesPathAsync(path)
.then(function (stat) {
if (stat !== undefined) {
return checkExistingFileFulfillsCriteriaAsync(path, stat, criteria);
}
return createBrandNewFileAsync(path, criteria);
})
.then(deferred.resolve, deferred.reject);
return deferred.promise;
checkWhatAlreadyOccupiesPathAsync(path)
.then(function (stat) {
if (stat !== undefined) {
return checkExistingFileFulfillsCriteriaAsync(path, stat, criteria);
}
return createBrandNewFileAsync(path, criteria);
})
.then(resolve, reject);
});
};

@@ -203,0 +193,0 @@

'use strict';
var pathUtil = require('path');
var Q = require('q');
var treeWalker = require('./utils/tree_walker');

@@ -95,29 +94,28 @@ var inspect = require('./inspect');

var findAsync = function (path, options) {
var deferred = Q.defer();
var foundInspectObjects = [];
var matchesAnyOfGlobs = matcher.create(path, options.matching);
return new Promise(function (resolve, reject) {
var foundInspectObjects = [];
var matchesAnyOfGlobs = matcher.create(path, options.matching);
var walker = treeWalker.stream(path, {
maxLevelsDeep: options.recursive ? Infinity : 1,
inspectOptions: {
absolutePath: true
}
})
.on('readable', function () {
var data = walker.read();
var item;
if (data && data.path !== path && matchesAnyOfGlobs(data.path)) {
item = data.item;
if ((item.type === 'file' && options.files === true)
|| (item.type === 'dir' && options.directories === true)) {
foundInspectObjects.push(item);
var walker = treeWalker.stream(path, {
maxLevelsDeep: options.recursive ? Infinity : 1,
inspectOptions: {
absolutePath: true
}
}
})
.on('error', deferred.reject)
.on('end', function () {
deferred.resolve(processFoundObjects(foundInspectObjects, options.cwd));
})
.on('readable', function () {
var data = walker.read();
var item;
if (data && data.path !== path && matchesAnyOfGlobs(data.path)) {
item = data.item;
if ((item.type === 'file' && options.files === true)
|| (item.type === 'dir' && options.directories === true)) {
foundInspectObjects.push(item);
}
}
})
.on('error', reject)
.on('end', function () {
resolve(processFoundObjects(foundInspectObjects, options.cwd));
});
});
return deferred.promise;
};

@@ -124,0 +122,0 @@

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

var pathUtil = require('path');
var Q = require('q');
var inspect = require('./inspect');

@@ -92,61 +91,57 @@ var list = require('./list');

var inspectTreeNodeAsync = function (path, options, parent) {
var deferred = Q.defer();
return new Promise(function (resolve, reject) {
var inspectAllChildren = function (treeBranch) {
return new Promise(function (resolve2, reject2) {
list.async(path).then(function (children) {
var doNext = function (index) {
var subPath;
if (index === children.length) {
if (options.checksum) {
// We are done, but still have to calculate checksum of whole directory.
treeBranch[options.checksum] = checksumOfDir(treeBranch.children, options.checksum);
}
resolve2();
} else {
subPath = pathUtil.join(path, children[index]);
inspectTreeNodeAsync(subPath, options, treeBranch)
.then(function (treeSubBranch) {
children[index] = treeSubBranch;
treeBranch.size += treeSubBranch.size || 0;
doNext(index + 1);
})
.catch(reject2);
}
};
var inspectAllChildren = function (treeBranch) {
var subDirDeferred = Q.defer();
treeBranch.children = children;
treeBranch.size = 0;
list.async(path).then(function (children) {
var doNext = function (index) {
var subPath;
if (index === children.length) {
if (options.checksum) {
// We are done, but still have to calculate checksum of whole directory.
treeBranch[options.checksum] = checksumOfDir(treeBranch.children, options.checksum);
}
subDirDeferred.resolve();
doNext(0);
});
});
};
inspect.async(path, options)
.then(function (treeBranch) {
if (!treeBranch) {
// Given path doesn't exist. We are done.
resolve(treeBranch);
} else {
if (options.relativePath) {
treeBranch.relativePath = generateTreeNodeRelativePath(parent, path);
}
if (treeBranch.type !== 'dir') {
resolve(treeBranch);
} else {
subPath = pathUtil.join(path, children[index]);
inspectTreeNodeAsync(subPath, options, treeBranch)
.then(function (treeSubBranch) {
children[index] = treeSubBranch;
treeBranch.size += treeSubBranch.size || 0;
doNext(index + 1);
inspectAllChildren(treeBranch)
.then(function () {
resolve(treeBranch);
})
.catch(subDirDeferred.reject);
.catch(reject);
}
};
treeBranch.children = children;
treeBranch.size = 0;
doNext(0);
});
return subDirDeferred.promise;
};
inspect.async(path, options)
.then(function (treeBranch) {
if (!treeBranch) {
// Given path doesn't exist. We are done.
deferred.resolve(treeBranch);
} else {
if (options.relativePath) {
treeBranch.relativePath = generateTreeNodeRelativePath(parent, path);
}
if (treeBranch.type !== 'dir') {
deferred.resolve(treeBranch);
} else {
inspectAllChildren(treeBranch)
.then(function () {
deferred.resolve(treeBranch);
})
.catch(deferred.reject);
}
}
})
.catch(deferred.reject);
return deferred.promise;
})
.catch(reject);
});
};

@@ -153,0 +148,0 @@

'use strict';
var fs = require('fs');
var crypto = require('crypto');
var pathUtil = require('path');
var Q = require('q');
var fs = require('./utils/fs');
var validate = require('./utils/validate');

@@ -120,20 +119,14 @@

var promisedStat = Q.denodeify(fs.stat);
var promisedLstat = Q.denodeify(fs.lstat);
var promisedReadlink = Q.denodeify(fs.readlink);
var fileChecksumAsync = function (path, algo) {
var deferred = Q.defer();
var hash = crypto.createHash(algo);
var s = fs.createReadStream(path);
s.on('data', function (data) {
hash.update(data);
return new Promise(function (resolve, reject) {
var hash = crypto.createHash(algo);
var s = fs.createReadStream(path);
s.on('data', function (data) {
hash.update(data);
});
s.on('end', function () {
resolve(hash.digest('hex'));
});
s.on('error', reject);
});
s.on('end', function () {
deferred.resolve(hash.digest('hex'));
});
s.on('error', deferred.reject);
return deferred.promise;
};

@@ -149,3 +142,3 @@

} else if (inspectObj.type === 'symlink') {
return promisedReadlink(path)
return fs.readlink(path)
.then(function (linkPath) {

@@ -156,31 +149,30 @@ inspectObj.pointsAt = linkPath;

}
return new Q(inspectObj);
return Promise.resolve(inspectObj);
};
var inspectAsync = function (path, options) {
var deferred = Q.defer();
var statOperation = promisedLstat;
options = options || {};
return new Promise(function (resolve, reject) {
var statOperation = fs.lstat;
options = options || {};
if (options.symlinks === 'follow') {
statOperation = promisedStat;
}
if (options.symlinks === 'follow') {
statOperation = fs.stat;
}
statOperation(path)
.then(function (stat) {
var inspectObj = createInspectObj(path, options, stat);
addExtraFieldsAsync(path, inspectObj, options)
.then(deferred.resolve, deferred.reject);
})
.catch(function (err) {
// Detection if path exists
if (err.code === 'ENOENT') {
// Doesn't exist. Return undefined instead of throwing.
deferred.resolve(undefined);
} else {
deferred.reject(err);
}
statOperation(path)
.then(function (stat) {
var inspectObj = createInspectObj(path, options, stat);
addExtraFieldsAsync(path, inspectObj, options)
.then(resolve, reject);
})
.catch(function (err) {
// Detection if path exists
if (err.code === 'ENOENT') {
// Doesn't exist. Return undefined instead of throwing.
resolve(undefined);
} else {
reject(err);
}
});
});
return deferred.promise;
};

@@ -187,0 +179,0 @@

@@ -7,4 +7,2 @@ /* eslint no-param-reassign:0 */

var pathUtil = require('path');
var Q = require('q');
var append = require('./append');

@@ -106,11 +104,10 @@ var dir = require('./dir');

dirAsync: function (path, criteria) {
var deferred = Q.defer();
var normalizedPath;
dir.validateInput('dirAsync', path, criteria);
normalizedPath = resolvePath(path);
dir.async(normalizedPath, criteria)
.then(function () {
deferred.resolve(cwd(normalizedPath));
}, deferred.reject);
return deferred.promise;
return new Promise(function (resolve, reject) {
var normalizedPath = resolvePath(path);
dir.async(normalizedPath, criteria)
.then(function () {
resolve(cwd(normalizedPath));
}, reject);
});
},

@@ -133,10 +130,10 @@

fileAsync: function (path, criteria) {
var deferred = Q.defer();
var that = this;
file.validateInput('fileAsync', path, criteria);
file.async(resolvePath(path), criteria)
.then(function () {
deferred.resolve(that);
}, deferred.reject);
return deferred.promise;
return new Promise(function (resolve, reject) {
file.async(resolvePath(path), criteria)
.then(function () {
resolve(that);
}, reject);
});
},

@@ -143,0 +140,0 @@

'use strict';
var fs = require('fs');
var Q = require('q');
var fs = require('./utils/fs');
var validate = require('./utils/validate');

@@ -32,21 +31,17 @@

var promisedReaddir = Q.denodeify(fs.readdir);
var listAsync = function (path) {
var deferred = Q.defer();
promisedReaddir(path)
.then(function (list) {
deferred.resolve(list);
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Doesn't exist. Return undefined instead of throwing.
deferred.resolve(undefined);
} else {
deferred.reject(err);
}
return new Promise(function (resolve, reject) {
fs.readdir(path)
.then(function (list) {
resolve(list);
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// Doesn't exist. Return undefined instead of throwing.
resolve(undefined);
} else {
reject(err);
}
});
});
return deferred.promise;
};

@@ -53,0 +48,0 @@

'use strict';
var pathUtil = require('path');
var fs = require('fs');
var Q = require('q');
var mkdirp = require('mkdirp');
var fs = require('./utils/fs');
var validate = require('./utils/validate');
var dir = require('./dir');
var exists = require('./exists');
var validate = require('./utils/validate');

@@ -41,3 +40,3 @@ var validateInput = function (methodName, from, to) {

// Some parent directory doesn't exist. Create it.
mkdirp.sync(pathUtil.dirname(to));
dir.createSync(pathUtil.dirname(to));
// Retry the attempt

@@ -54,54 +53,47 @@ fs.renameSync(from, to);

var promisedRename = Q.denodeify(fs.rename);
var promisedMkdirp = Q.denodeify(mkdirp);
var ensureDestinationPathExistsAsync = function (to) {
var deferred = Q.defer();
var destDir = pathUtil.dirname(to);
exists.async(destDir)
.then(function (dstExists) {
if (!dstExists) {
promisedMkdirp(destDir)
.then(deferred.resolve, deferred.reject);
} else {
// Hah, no idea.
deferred.reject();
}
})
.catch(deferred.reject);
return deferred.promise;
return new Promise(function (resolve, reject) {
var destDir = pathUtil.dirname(to);
exists.async(destDir)
.then(function (dstExists) {
if (!dstExists) {
dir.createAsync(destDir)
.then(resolve, reject);
} else {
// Hah, no idea.
reject();
}
})
.catch(reject);
});
};
var moveAsync = function (from, to) {
var deferred = Q.defer();
promisedRename(from, to)
.then(deferred.resolve)
.catch(function (err) {
if (err.code !== 'ENOENT') {
// Something unknown. Rethrow original error.
deferred.reject(err);
} else {
// Ok, source or destination path doesn't exist.
// Must do more investigation.
exists.async(from)
.then(function (srcExists) {
if (!srcExists) {
deferred.reject(generateSourceDoesntExistError(from));
} else {
ensureDestinationPathExistsAsync(to)
.then(function () {
// Retry the attempt
return promisedRename(from, to);
})
.then(deferred.resolve, deferred.reject);
}
})
.catch(deferred.reject);
}
return new Promise(function (resolve, reject) {
fs.rename(from, to)
.then(resolve)
.catch(function (err) {
if (err.code !== 'ENOENT') {
// Something unknown. Rethrow original error.
reject(err);
} else {
// Ok, source or destination path doesn't exist.
// Must do more investigation.
exists.async(from)
.then(function (srcExists) {
if (!srcExists) {
reject(generateSourceDoesntExistError(from));
} else {
ensureDestinationPathExistsAsync(to)
.then(function () {
// Retry the attempt
return fs.rename(from, to);
})
.then(resolve, reject);
}
})
.catch(reject);
}
});
});
return deferred.promise;
};

@@ -108,0 +100,0 @@

@@ -5,4 +5,3 @@ /* eslint no-console:1 */

var fs = require('fs');
var Q = require('q');
var fs = require('./utils/fs');
var validate = require('./utils/validate');

@@ -83,39 +82,35 @@

var promisedReadFile = Q.denodeify(fs.readFile);
var readAsync = function (path, returnAs) {
var deferred = Q.defer();
return new Promise(function (resolve, reject) {
var retAs = returnAs || 'utf8';
var encoding = 'utf8';
if (retAs === 'buffer') {
encoding = null;
}
var retAs = returnAs || 'utf8';
var encoding = 'utf8';
if (retAs === 'buffer') {
encoding = null;
}
promisedReadFile(path, { encoding: encoding })
.then(function (data) {
// Make final parsing of the data before returning.
try {
if (retAs === 'json') {
deferred.resolve(JSON.parse(data));
} else if (retAs === 'jsonWithDates') {
deferred.resolve(JSON.parse(data, jsonDateParser));
fs.readFile(path, { encoding: encoding })
.then(function (data) {
// Make final parsing of the data before returning.
try {
if (retAs === 'json') {
resolve(JSON.parse(data));
} else if (retAs === 'jsonWithDates') {
resolve(JSON.parse(data, jsonDateParser));
} else {
resolve(data);
}
} catch (err) {
reject(makeNicerJsonParsingError(path, err));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// If file doesn't exist return undefined instead of throwing.
resolve(undefined);
} else {
deferred.resolve(data);
// Otherwise throw
reject(err);
}
} catch (err) {
deferred.reject(makeNicerJsonParsingError(path, err));
}
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// If file doesn't exist return undefined instead of throwing.
deferred.resolve(undefined);
} else {
// Otherwise throw
deferred.reject(err);
}
});
});
return deferred.promise;
};

@@ -122,0 +117,0 @@

'use strict';
var Q = require('q');
var rimraf = require('rimraf');
var pathUtil = require('path');
var fs = require('./utils/fs');
var validate = require('./utils/validate');
var list = require('./list');

@@ -18,3 +18,21 @@ var validateInput = function (methodName, path) {

var removeSync = function (path) {
rimraf.sync(path);
try {
// Assume the path is a file and just try to remove it.
fs.unlinkSync(path);
} catch (err) {
if (err.code === 'EPERM' || err.code === 'EISDIR' || err.code === 'ENOTEMPTY') {
// Must delete everything inside the directory first.
list.sync(path).forEach(function (filename) {
removeSync(pathUtil.join(path, filename));
});
// Everything inside directory has been removed,
// it's safe now do go for the directory itself.
fs.rmdirSync(path);
} else if (err.code === 'ENOENT') {
// File already doesn't exist. We're done.
} else {
// Something unexpected happened. Rethrow original error.
throw err;
}
}
};

@@ -26,6 +44,32 @@

var qRimraf = Q.denodeify(rimraf);
var removeAsync = function (path) {
return qRimraf(path);
return new Promise(function (resolve, reject) {
// Assume the path is a file and just try to remove it.
fs.unlink(path)
.then(resolve)
.catch(function (err) {
if (err.code === 'EPERM' || err.code === 'EISDIR' || err.code === 'ENOTEMPTY') {
// It's not a file, it's a directory.
// Must delete everything inside first.
list.async(path).then(function (filenamesInsideDir) {
var promises = filenamesInsideDir.map(function (filename) {
return removeAsync(pathUtil.join(path, filename));
});
return Promise.all(promises);
})
.then(function () {
// Everything inside directory has been removed,
// it's safe now to go for the directory itself.
return fs.rmdir(path);
})
.then(resolve, reject);
} else if (err.code === 'ENOENT') {
// File already doesn't exist. We're done.
resolve();
} else {
// Something unexpected happened. Rethrow original error.
reject(err);
}
});
});
};

@@ -32,0 +76,0 @@

'use strict';
var Q = require('q');
var fs = require('fs');
var mkdirp = require('mkdirp');
var pathUtil = require('path');
var fs = require('./utils/fs');
var validate = require('./utils/validate');
var dir = require('./dir');

@@ -25,3 +24,3 @@ var validateInput = function (methodName, symlinkValue, path) {

// Parent directories don't exist. Just create them and rety.
mkdirp.sync(pathUtil.dirname(path));
dir.createSync(pathUtil.dirname(path));
fs.symlinkSync(symlinkValue, path);

@@ -38,24 +37,19 @@ } else {

var promisedSymlink = Q.denodeify(fs.symlink);
var promisedMkdirp = Q.denodeify(mkdirp);
var symlinkAsync = function (symlinkValue, path) {
var deferred = Q.defer();
promisedSymlink(symlinkValue, path)
.then(deferred.resolve)
.catch(function (err) {
if (err.code === 'ENOENT') {
// Parent directories don't exist. Just create them and rety.
promisedMkdirp(pathUtil.dirname(path))
.then(function () {
return promisedSymlink(symlinkValue, path);
})
.then(deferred.resolve, deferred.reject);
} else {
deferred.reject(err);
}
return new Promise(function (resolve, reject) {
fs.symlink(symlinkValue, path)
.then(resolve)
.catch(function (err) {
if (err.code === 'ENOENT') {
// Parent directories don't exist. Just create them and rety.
dir.createAsync(pathUtil.dirname(path))
.then(function () {
return fs.symlink(symlinkValue, path);
})
.then(resolve, reject);
} else {
reject(err);
}
});
});
return deferred.promise;
};

@@ -62,0 +56,0 @@

'use strict';
var fs = require('fs');
var Q = require('q');
var mkdirp = require('mkdirp');
var pathUtil = require('path');
var fs = require('./utils/fs');
var validate = require('./utils/validate');
var dir = require('./dir');

@@ -47,3 +46,3 @@ var validateInput = function (methodName, path, data, options) {

// Means parent directory doesn't exist, so create it and try again.
mkdirp.sync(pathUtil.dirname(path));
dir.createSync(pathUtil.dirname(path));
fs.writeFileSync(path, data, options);

@@ -80,44 +79,36 @@ } else {

var promisedRename = Q.denodeify(fs.rename);
var promisedWriteFile = Q.denodeify(fs.writeFile);
var promisedMkdirp = Q.denodeify(mkdirp);
var writeFileAsync = function (path, data, options) {
var deferred = Q.defer();
promisedWriteFile(path, data, options)
.then(deferred.resolve)
.catch(function (err) {
// First attempt to write a file ended with error.
// Check if this is not due to nonexistent parent directory.
if (err.code === 'ENOENT') {
// Parent directory doesn't exist, so create it and try again.
promisedMkdirp(pathUtil.dirname(path))
.then(function () {
return promisedWriteFile(path, data, options);
})
.then(deferred.resolve, deferred.reject);
} else {
// Nope, some other error, throw it.
deferred.reject(err);
}
return new Promise(function (resolve, reject) {
fs.writeFile(path, data, options)
.then(resolve)
.catch(function (err) {
// First attempt to write a file ended with error.
// Check if this is not due to nonexistent parent directory.
if (err.code === 'ENOENT') {
// Parent directory doesn't exist, so create it and try again.
dir.createAsync(pathUtil.dirname(path))
.then(function () {
return fs.writeFile(path, data, options);
})
.then(resolve, reject);
} else {
// Nope, some other error, throw it.
reject(err);
}
});
});
return deferred.promise;
};
var writeAtomicAsync = function (path, data, options) {
var deferred = Q.defer();
// We are assuming there is file on given path, and we don't want
// to touch it until we are sure our data has been saved correctly,
// so write the data into temporary file...
writeFileAsync(path + newExt, data, options)
.then(function () {
// ...next rename temp file to real path.
return promisedRename(path + newExt, path);
})
.then(deferred.resolve, deferred.reject);
return deferred.promise;
return new Promise(function (resolve, reject) {
// We are assuming there is file on given path, and we don't want
// to touch it until we are sure our data has been saved correctly,
// so write the data into temporary file...
writeFileAsync(path + newExt, data, options)
.then(function () {
// ...next rename temp file to real path.
return fs.rename(path + newExt, path);
})
.then(resolve, reject);
});
};

@@ -124,0 +115,0 @@

{
"name": "fs-jetpack",
"description": "Better file system API",
"version": "0.12.0",
"version": "0.13.0",
"author": "Jakub Szwacz <jakub@szwacz.com>",
"dependencies": {
"minimatch": "^3.0.2",
"mkdirp": "^0.5.1",
"q": "^1.0.1",
"rimraf": "^2.2.8"
"minimatch": "^3.0.2"
},

@@ -20,2 +17,3 @@ "devDependencies": {

"istanbul": "^0.4.5",
"lint-staged": "^3.4.0",
"mocha": "^3.1.2",

@@ -25,2 +23,5 @@ "pre-commit": "^1.1.2",

},
"engines": {
"node": ">=4"
},
"scripts": {

@@ -30,2 +31,3 @@ "test": "mocha \"spec/**/*.spec.js\"",

"lint": "eslint .",
"lint-staged": "lint-staged",
"release-start": "release-assist --start",

@@ -45,6 +47,9 @@ "release-finish": "release-assist --finish"

],
"lint-staged": {
"*.js": "eslint"
},
"pre-commit": [
"lint",
"lint-staged",
"test"
]
}

@@ -1,2 +0,1 @@

var Q = require('q');
var fse = require('fs-extra');

@@ -165,10 +164,13 @@ var expect = require('chai').expect;

it('async', function (done) {
Q.spread([
jetpack.readAsync('nonexistent.txt'),
jetpack.readAsync('nonexistent.txt', 'json'),
jetpack.readAsync('nonexistent.txt', 'buffer')
], function (content1, content2, content3) {
expectations(content1);
expectations(content2);
expectations(content3);
jetpack.readAsync('nonexistent.txt')
.then(function (content) {
expectations(content);
return jetpack.readAsync('nonexistent.txt', 'json');
})
.then(function (content) {
expectations(content);
return jetpack.readAsync('nonexistent.txt', 'buffer');
})
.then(function (content) {
expectations(content);
done();

@@ -175,0 +177,0 @@ });

@@ -104,3 +104,3 @@ var fse = require('fs-extra');

describe('can be called witn no parameters, what will remove CWD directory', function () {
describe('can be called with no parameters, what will remove CWD directory', function () {
var preparations = function () {

@@ -107,0 +107,0 @@ fse.outputFileSync('a/b/c.txt', 'abc');

@@ -1,2 +0,1 @@

var Q = require('q');
var fse = require('fs-extra');

@@ -95,3 +94,3 @@ var expect = require('chai').expect;

it('async', function (done) {
Q.all([
Promise.all([
jetpack.writeAsync('a.json', obj, { jsonIndent: 0 }),

@@ -98,0 +97,0 @@ jetpack.writeAsync('b.json', obj), // Default indent = 2

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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