Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fsu

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fsu - npm Package Compare versions

Comparing version 1.1.1 to 2.0.0

170

index.js

@@ -9,12 +9,12 @@ 'use strict';

const defaultDirMode = parseInt('0777', 8) & (~process.umask());
const defaultFileMode = parseInt('0666', 8) & (~process.umask());
const defaultDirMode = 0o777 & (~process.umask());
const defaultFileMode = 0o666 & (~process.umask());
const padNum = function(n, width, z) {
z = z || '0';
n += '';
n = String(n);
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
};
const writeAll = function(fd, buffer, offset, length, position, cb) {
function writeAll(fd, buffer, offset, length, position, cb) {
fs.write(fd, buffer, offset, length, position, (writeErr, written) => {

@@ -32,46 +32,43 @@ if (writeErr) {

});
};
}
const mkdirp = function(p, mode, cb) {
fs.mkdir(p, mode, err => {
if (!err) {
cb();
} else if (err.code === 'ENOENT') {
mkdirp(path.dirname(p), mode, err => {
if (err) {
cb(err);
} else {
mkdirp(p, mode, cb);
}
});
} else if (err.code === 'EEXIST') {
cb();
} else {
cb(err);
}
});
};
function writeAllAsync(fd, buffer, offset, length, position) {
return new Promise((resolve, reject) => {
writeAll(fd, buffer, offset, length, position, err => {
if (err) {
return reject(err);
}
const openUniqueHandler = function(tryNum, fileParts, options, cb) {
resolve();
})
})
}
async function openUniqueHandler(tryNum, fileParts, options) {
const file = options.simple ? fileParts.tail : tryNum ? (fileParts.head + fileParts.padLeft + padNum(tryNum, fileParts.pad) + fileParts.padRight + fileParts.tail) : (fileParts.head + fileParts.tail);
const newPath = path.join(fileParts.path, file);
fs.open(newPath, options.flags || 'w', options.mode || defaultFileMode, (err, fd) => {
if (err && err.code === 'EEXIST' && !options.simple) {
openUniqueHandler(++tryNum, fileParts, options, cb);
} else if (err && err.code === 'ENOENT' && options.force) {
mkdirp(fileParts.path, defaultDirMode, ere => {
if (ere) {
cb(ere);
} else {
openUniqueHandler(tryNum, fileParts, options, cb);
}
try {
const fd = await fs.promises.open(newPath, options.flags || 'w', options.mode || defaultFileMode);
return {
fd: fd.fd,
path: newPath
};
} catch (err) {
if (err.code === 'EEXIST' && !options.simple) {
return openUniqueHandler(++tryNum, fileParts, options);
} else if (err.code === 'ENOENT' && options.force) {
await fs.promises.mkdir(fileParts.path, {
mode: defaultDirMode,
recursive: true
});
} else {
cb(err, fd, newPath);
return openUniqueHandler(tryNum, fileParts, options);
}
});
};
const openUnique = function(file, options, cb) {
throw err;
}
}
function openUnique(file, options) {
file = path.resolve(file);

@@ -85,70 +82,51 @@ const filePath = path.dirname(file);

options.simple = true;
openUniqueHandler(0, {
return openUniqueHandler(0, {
path: filePath,
tail: fileName
}, options, cb);
} else {
options.simple = false;
options.flags = 'wx';
openUniqueHandler(0, {
path: filePath,
head: fileParts[1] || '',
padLeft: fileParts[2],
pad: fileParts[3].length,
padRight: fileParts[4],
tail: fileParts[5] || ''
}, options, cb);
}, options);
}
};
const writeFileUnique = function(filename, data, options, cb) {
if (cb === undefined) {
cb = options;
options = {
encoding: 'utf8',
mode: defaultFileMode,
flags: 'w'
};
}
options.simple = false;
options.flags = 'wx';
return openUniqueHandler(0, {
path: filePath,
head: fileParts[1] || '',
padLeft: fileParts[2],
pad: fileParts[3].length,
padRight: fileParts[4],
tail: fileParts[5] || ''
}, options);
}
openUnique(filename, options, (err, fd, newPath) => {
if (err) {
cb(err);
} else {
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(String(data), options.encoding || 'utf8');
writeAll(fd, buffer, 0, buffer.length, 0, err => cb(err, newPath));
}
});
};
async function writeFileUnique(filename, data, options = { encoding: 'utf8', mode: defaultFileMode, flags: 'w' }) {
const { fd, path } = await openUnique(filename, options);
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(String(data), options.encoding || 'utf8');
await writeAllAsync(fd, buffer, 0, buffer.length, 0);
return path;
}
// stream
const WriteStreamUnique = function(file, options) {
if (options && options.force) {
this.force = options.force;
delete options.force;
}
function WriteStreamUnique(file, options = {}) {
this.force = options.force;
WriteStream.call(this, file, options);
};
}
inherits(WriteStreamUnique, WriteStream);
WriteStreamUnique.prototype.open = function() {
openUnique(this.path, {
flags: this.flags,
mode: this.mode,
force: this.force
}, (err, fd, newPath) => {
if (err) {
this.destroy();
this.emit('error', err);
return;
}
this.path = newPath;
WriteStreamUnique.prototype.open = async function() {
try {
const { fd, path } = await openUnique(this.path, {
flags: this.flags,
mode: this.mode,
force: this.force
});
this.path = path;
this.fd = fd;
this.emit('open', fd);
});
};
this.emit('open', this.fd);
} catch (e) {
this.destroy();
this.emit('error', e);
}
}
const createWriteStreamUnique = function(file, options) {
return new WriteStreamUnique(file, options);
};
const createWriteStreamUnique = (file, options) => new WriteStreamUnique(file, options);

@@ -155,0 +133,0 @@ module.exports = {

@@ -26,7 +26,7 @@ {

},
"version": "1.1.1",
"version": "2.0.0",
"devDependencies": {
"ava": "^0.25.0",
"del": "^3.0.0",
"nyc": "^11.7.1"
"ava": "^2.0.0",
"del": "^5.0.0",
"nyc": "^14.0.0"
},

@@ -33,0 +33,0 @@ "scripts": {

@@ -13,3 +13,3 @@ # fsu (fs unique)

## openUnique(path, [mode], callback)
## async openUnique(path, [mode])
Same as [fs.open](http://nodejs.org/api/fs.html#fs_fs_open_path_flags_mode_callback) but open for writing and creates unique filename.

@@ -20,8 +20,7 @@

fsu.openUnique("text{_###}.txt", (err, fd, path) => {
//now we can use file descriptor as usual
});
const { fd, path } = await fsu.openUnique("text{_###}.txt", [options]);
```
## writeFileUnique(path, data, [options], callback)
## async writeFileUnique(path, data, [options])
Same as [fs.writeFile](http://nodejs.org/api/fs.html#fs_fs_writefile_filename_data_options_callback) but creates unique filename.

@@ -32,5 +31,4 @@

fsu.writeFileUnique("text{_###}.txt", "test", (err, path) => {
console.log("Done", path);
});
const path = await fsu.writeFileUnique("text{_###}.txt", "test");
```

@@ -37,0 +35,0 @@

@@ -11,15 +11,14 @@ 'use strict';

test.serial.cb('write unique file with callbacks', t => {
fsu.writeFileUnique(path.join('test', 'test{_file###}.txt'), 'test', { force: true }, (err, path) => {
if (err) {
t.fail(err);
} else {
t.true(path.endsWith('test.txt'));
}
t.end();
});
test.serial('write unique file', async t => {
const filePath = await fsu.writeFileUnique(path.join('test', 'test{_file###}.txt'), 'test', { force: true });
t.true(filePath.endsWith('test.txt'));
});
test.serial.cb('write unique file and stream with callbacks', t => {
const stream = fsu.createWriteStreamUnique(path.join('test', 'test{_stream###}.txt'));
test.serial('write file with a file name without pattern', async t => {
const filePath = await fsu.writeFileUnique(path.join('test', 'test1.txt'), 'test', { force: true });
t.true(filePath.endsWith('test1.txt'));
});
test.serial.cb('writes unique file with fs stream', t => {
const stream = fsu.createWriteStreamUnique(path.join('test', 'test{_stream###}.txt'), { force: true });
fs.createReadStream('readme.md').pipe(stream).on('finish', () => {

@@ -31,1 +30,17 @@ t.true(stream.path.endsWith('test_stream001.txt'));

test.serial.cb('fails to write unique file with a stream to non existed directory', t => {
const stream = fsu.createWriteStreamUnique(path.join('nonexisted', 'test{_stream###}.txt'));
fs.createReadStream('readme.md').pipe(stream)
.on('finish', () => t.fail())
.on('error', () => t.end())
});
test.serial.cb('writes big unique file with fs stream', t => {
const stream = fsu.createWriteStreamUnique(path.join('test', 'test{_stream###}.txt'), { force: true });
fs.createReadStream('package-lock.json')
.pipe(stream)
.on('finish', () => {
t.true(stream.path.endsWith('test_stream002.txt'));
t.end();
});
});
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