From 5187bf3dc47576f5935908cbb60c807d5511c6da Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Sat, 31 Oct 2020 20:27:06 +0530 Subject: [PATCH] Add option to override final EOL in file (#137) --- .gitignore | 2 ++ README.md | 29 +++++++++++++++++++++++-- test/write-file-sync.test.js | 34 ++++++++++++++++++++++++++++++ test/write-file.test.js | 41 ++++++++++++++++++++++++++++++++++++ utils.js | 9 ++++---- 5 files changed, 108 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 2feef5e..217d377 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules/ /.project +.vscode/ + diff --git a/README.md b/README.md index 71da02f..910cde0 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ console.dir(jsonfile.readFileSync(file)) ### writeFile(filename, obj, [options], callback) -`options`: Pass in any [`fs.writeFile`](https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback) options or set `replacer` for a [JSON replacer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Can also pass in `spaces` and override `EOL` string. +`options`: Pass in any [`fs.writeFile`](https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback) options or set `replacer` for a [JSON replacer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Can also pass in `spaces`, or override `EOL` string or set `finalEOL` flag as `false` to not save the file with `EOL` at the end. ```js @@ -132,6 +132,20 @@ jsonfile.writeFile(file, obj, { spaces: 2, EOL: '\r\n' }, function (err) { }) ``` + +**disabling the EOL at the end of file:** + +```js +const jsonfile = require('jsonfile') + +const file = '/tmp/data.json' +const obj = { name: 'JP' } + +jsonfile.writeFile(file, obj, { spaces: 2, finalEOL: false }, function (err) { + if (err) console.log(err) +}) +``` + **appending to an existing JSON file:** You can use `fs.writeFile` option `{ flag: 'a' }` to achieve this. @@ -151,7 +165,7 @@ jsonfile.writeFile(file, obj, { flag: 'a' }, function (err) { ### writeFileSync(filename, obj, [options]) -`options`: Pass in any [`fs.writeFileSync`](https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options) options or set `replacer` for a [JSON replacer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Can also pass in `spaces` and override `EOL` string. +`options`: Pass in any [`fs.writeFileSync`](https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options) options or set `replacer` for a [JSON replacer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Can also pass in `spaces`, or override `EOL` string or set `finalEOL` flag as `false` to not save the file with `EOL` at the end. ```js const jsonfile = require('jsonfile') @@ -184,6 +198,17 @@ const obj = { name: 'JP' } jsonfile.writeFileSync(file, obj, { spaces: 2, EOL: '\r\n' }) ``` +**disabling the EOL at the end of file:** + +```js +const jsonfile = require('jsonfile') + +const file = '/tmp/data.json' +const obj = { name: 'JP' } + +jsonfile.writeFileSync(file, obj, { spaces: 2, finalEOL: false }) +``` + **appending to an existing JSON file:** You can use `fs.writeFileSync` option `{ flag: 'a' }` to achieve this. diff --git a/test/write-file-sync.test.js b/test/write-file-sync.test.js index 6b0dba2..26340da 100644 --- a/test/write-file-sync.test.js +++ b/test/write-file-sync.test.js @@ -82,4 +82,38 @@ describe('+ writeFileSync()', () => { assert.strictEqual(data, `${JSON.stringify(obj)}\n`) }) }) + describe('> when EOF option is set to a falsey value', () => { + beforeEach((done) => { + TEST_DIR = path.join(os.tmpdir(), 'jsonfile-tests-writefile-sync') + rimraf.sync(TEST_DIR) + fs.mkdir(TEST_DIR, done) + }) + + afterEach((done) => { + rimraf.sync(TEST_DIR) + done() + }) + + it('should not have a the EOL symbol at the end of file', (done) => { + const file = path.join(TEST_DIR, 'somefile2.json') + const obj = { name: 'jp' } + jf.writeFileSync(file, obj, { finalEOL: false }) + const rawData = fs.readFileSync(file, 'utf8') + const data = JSON.parse(rawData) + assert.strictEqual(rawData[rawData.length - 1], '}') + assert.strictEqual(data.name, obj.name) + done() + }) + + it('should have a the EOL symbol at the end of file when finalEOL is a truth value in options', (done) => { + const file = path.join(TEST_DIR, 'somefile2.json') + const obj = { name: 'jp' } + jf.writeFileSync(file, obj, { finalEOL: true }) + const rawData = fs.readFileSync(file, 'utf8') + const data = JSON.parse(rawData) + assert.strictEqual(rawData[rawData.length - 1], '\n') + assert.strictEqual(data.name, obj.name) + done() + }) + }) }) diff --git a/test/write-file.test.js b/test/write-file.test.js index 64e3253..8f3bc28 100644 --- a/test/write-file.test.js +++ b/test/write-file.test.js @@ -199,6 +199,47 @@ describe('+ writeFile()', () => { }) }) + describe('> when EOF option is set to a falsey value', () => { + beforeEach((done) => { + TEST_DIR = path.join(os.tmpdir(), 'jsonfile-tests-writefile') + rimraf.sync(TEST_DIR) + fs.mkdir(TEST_DIR, done) + }) + + afterEach((done) => { + rimraf.sync(TEST_DIR) + done() + }) + + it('should not have a the EOL symbol at the end of file', (done) => { + const file = path.join(TEST_DIR, 'somefile2.json') + const obj = { name: 'jp' } + jf.writeFile(file, obj, { finalEOL: false }, (err) => { + assert.ifError(err) + fs.readFile(file, 'utf8', (_, rawData) => { + const data = JSON.parse(rawData) + assert.strictEqual(rawData[rawData.length - 1], '}') + assert.strictEqual(data.name, obj.name) + done() + }) + }) + }) + + it('should have a the EOL symbol at the end of file when finalEOL is a truth value in options', (done) => { + const file = path.join(TEST_DIR, 'somefile2.json') + const obj = { name: 'jp' } + jf.writeFile(file, obj, { finalEOL: true }, (err) => { + assert.ifError(err) + fs.readFile(file, 'utf8', (_, rawData) => { + const data = JSON.parse(rawData) + assert.strictEqual(rawData[rawData.length - 1], '\n') + assert.strictEqual(data.name, obj.name) + done() + }) + }) + }) + }) + // Prevent https://github.com/jprichardson/node-jsonfile/issues/81 from happening describe("> when callback isn't passed & can't serialize", () => { it('should not write an empty file, should reject the promise', function (done) { diff --git a/utils.js b/utils.js index b23697f..b5ff48e 100644 --- a/utils.js +++ b/utils.js @@ -1,9 +1,8 @@ -function stringify (obj, options = {}) { - const EOL = options.EOL || '\n' +function stringify (obj, { EOL = '\n', finalEOL = true, replacer = null, spaces } = {}) { + const EOF = finalEOL ? EOL : '' + const str = JSON.stringify(obj, replacer, spaces) - const str = JSON.stringify(obj, options ? options.replacer : null, options.spaces) - - return str.replace(/\n/g, EOL) + EOL + return str.replace(/\n/g, EOL) + EOF } function stripBom (content) {