Skip to content

Commit

Permalink
Merge pull request #15 from Richienb/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
hemanth authored Jul 29, 2020
2 parents 503e60a + e660df7 commit c74ac10
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 284 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.nyc_output
yarn.lock
package-lock.json
/node_modules/
npm-debug.log
.idea
5 changes: 0 additions & 5 deletions .jscsrc

This file was deleted.

15 changes: 0 additions & 15 deletions .jshintrc

This file was deleted.

1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sudo: false
language: node_js
node_js:
- 'iojs'
- '0.12'
- '0.10'
after_script: NODE_ENV=test istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage
- "14"
- "12"

after_success: npm run coverage
31 changes: 31 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
declare const prependFile: {
/**
Synchronously prepend data to a file, creating it if it doesn't exist.
@param filename The file to prepend the `data` to.
@param data The data to prepend.
@example
```
const prependFile = require('prepend-file');
prependFile.sync('message.txt', 'some data');
```
*/
sync: (filename: string, data: string | Buffer) => void;

/**
Prepend data to a file, creating it if it doesn't exist.
@param filename The file to prepend the `data` to.
@param data The data to prepend.
@example
```
const prependFile = require('prepend-file');
(async () => {
await prependFile('message.txt', 'some data');
});
```
*/
(filename: string, data: string | Buffer): Promise<void>;
};

export = prependFile;
151 changes: 21 additions & 130 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,136 +1,27 @@
'use strict';
var fs = require('fs');
var util = require('util');
var tmp = require('tmp');

var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);

function rethrow() {
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and is fairly slow to generate.
if (DEBUG) {
var backtrace = new Error();
return function(err) {
if (err) {
backtrace.stack = err.name + ': ' + err.message +
backtrace.stack.substr(backtrace.name.length);
err = backtrace;
throw err;
}
};
}

return function(err) {
if (err) {
throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
}
};
}

function maybeCallback(callback) {
return typeof callback === 'function' ? callback : rethrow();
}

module.exports = function prependFile(path, data, options) {
var callback = maybeCallback(arguments[arguments.length - 1]);

if (typeof options === 'function' || !options) {
options = {
encoding: 'utf8',
mode: 438 /*=0666*/
};
} else if (util.isString(options)) {
options = {
encoding: options,
mode: 438
};
} else if (!util.isObject(options)) {
throw new TypeError('Bad arguments');
const fs = require('fs');
const {promisify} = require('util');
const tempWrite = require('temp-write');
const pathExists = require('path-exists');
const pipeline = promisify(require('stream').pipeline);

module.exports = async (filename, data) => {
if (await pathExists(filename)) {
const temporaryFile = await tempWrite(data);

await pipeline(fs.createReadStream(filename), fs.createWriteStream(temporaryFile, {flags: 'a'}));
await pipeline(fs.createReadStream(temporaryFile), fs.createWriteStream(filename));

await fs.promises.unlink(temporaryFile);
} else {
await fs.promises.writeFile(filename, data);
}

var appendOptions = {
encoding: options.encoding,
mode: options.mode,
flags: 'a'
};

// a temp file is written even if dist file does not exist. PR welcome for better implementation.
tmp
.file(function (err, tempFilePath, fd, cleanupCallback) {
if (err) {
callback(err);
return;
}

fs.writeFile(tempFilePath, data, options, function (err) {
if (err) {
callback(err);
return;
}

fs.createReadStream(path, options)
.on('error', function(err) {
if (err.code === 'ENOENT' /*file does not exist*/) {
fs.writeFile(path, data, options, function (err) {
if (err) {
callback(err);
} else {
callback();
}
});
} else {
callback(err);
}
})
.pipe(fs.createWriteStream(tempFilePath, appendOptions))
.on('error', function(err) {
callback(err);
})
.on('finish', function() {
fs.createReadStream(tempFilePath, options)
.on('error', function(err) {
callback(err);
})
.pipe(fs.createWriteStream(path, options))
.on('error', function(err) {
callback(err);
})
.on('finish', function() {
cleanupCallback();
callback();
});
});
});
});
};

module.exports.sync = function sync(path, data, options) {
if (!options) {
options = {
encoding: 'utf8',
mode: 438 /*=0666*/
};
} else if (util.isString(options)) {
options = {
encoding: options,
mode: 438
};
} else if (!util.isObject(options)) {
throw new TypeError('Bad arguments');
}

var currentFileData;

var appendOptions = {
encoding: options.encoding,
mode: options.mode,
flags: 'w'
};

try {
currentFileData = fs.readFileSync(path, options);
} catch (err) {
currentFileData = '';
module.exports.sync = (filename, data) => {
if (pathExists.sync(filename)) {
fs.writeFileSync(filename, Buffer.concat([Buffer.from(data), fs.readFileSync(filename)]));
} else {
fs.writeFileSync(filename, data);
}

fs.writeFileSync(path, data + currentFileData, appendOptions);
};
27 changes: 15 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,32 @@
"url": "http://h3manth.com"
},
"engines": {
"node": ">=0.10.0"
"node": ">=10.17 <11 || >=11.14"
},
"scripts": {
"coverage": "istanbul cover _mocha -- -R spec && rm -rf ./coverage",
"lint": "jshint *.js --exclude node_modules && jscs *.js",
"test": "mocha"
"coverage": "nyc report --reporter=text-lcov | coveralls",
"test": "xo && nyc ava"
},
"files": [
"index.js"
"index.js",
"index.d.ts"
],
"keywords": [
"fs",
"file",
"prepend"
],
"dependencies": {
"path-exists": "^4.0.0",
"temp-write": "^4.0.0"
},
"devDependencies": {
"coveralls": "^2.11.2",
"istanbul": "^0.3.13",
"jscs": "^1.13.1",
"jshint": "^2.6.3",
"mocha": "*"
"ava": "^3.11.0",
"coveralls": "^3.1.0",
"nyc": "^15.1.0",
"xo": "^0.32.1"
},
"dependencies": {
"tmp": "0.0.31"
"xo": {
"space": 2
}
}
48 changes: 14 additions & 34 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,42 @@
# [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url]

> Prepend data to a file, creating the file if it not yet exists.
# prepend-file [![Build Status][travis-image]][travis-url] [![Code Coverage][coveralls-image]][coveralls-url]

> Prepend data to a file, creating it if it doesn't exist.
## Install

```sh
$ npm install --save prepend-file
npm install prepend-file
```

## Usage

```js
var prependFile = require('prepend-file');

prependFile('message.txt', 'data to prepend', function (err) {
if (err) {
// Error
}
const prependFile = require('prepend-file');

// Success
console.log('The "data to prepend" was prepended to file!');
(async () => {
await prependFile('message.txt', 'some data');
});
```

## API

### prependFile(filename, data, [options], callback)

```
* filename String
* data String | Buffer
* options Object
encoding String | Null default = 'utf8'
mode Number default = 438 (aka 0666 in Octal)
* callback Function
```

Asynchronously prepend data to a file, creating the file if it not yet exists. The `data` can be a string or a buffer.
### prependFile(filename, data)

### prependFile.sync(filename, data, [options])
### prependFile.sync(filename, data)

The synchronous version of `prependFile`. Returns `undefined`.
#### filename

## Related
Type: `string`

* [prepend-file-cli](https://github.com/martinvd/prepend-file-cli)
The file to prepend the `data` to.

## License
#### data

MIT © [Hemanth.HM](http://h3manth.com)
Type: `string | Buffer`

The data to prepend.

[npm-image]: https://badge.fury.io/js/prepend-file.svg
[npm-url]: https://npmjs.org/package/prepend-file
[travis-image]: https://travis-ci.org/hemanth/node-prepend-file.svg?branch=master
[travis-url]: https://travis-ci.org/hemanth/node-prepend-file
[daviddm-image]: https://david-dm.org/hemanth/node-prepend-file.svg?theme=shields.io
[daviddm-url]: https://david-dm.org/hemanth/node-prepend-file
[coveralls-image]: https://coveralls.io/repos/hemanth/node-prepend-file/badge.svg
[coveralls-url]: https://coveralls.io/r/hemanth/node-prepend-file
Loading

0 comments on commit c74ac10

Please sign in to comment.