Skip to content

Commit 0e5f6ad

Browse files
committed
Require Node.js 8
1 parent 73b8041 commit 0e5f6ad

File tree

6 files changed

+77
-81
lines changed

6 files changed

+77
-81
lines changed

index.d.ts

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
declare namespace writeJsonFile {
22
type Replacer = (this: unknown, key: string, value: any) => unknown;
33
type SortKeys = (a: string, b: string) => number;
4-
type JSONStringifyable = string | number | boolean | null | object;
54

65
interface Options {
76
/**
8-
Indentation as a string or number of spaces. Pass in null for no formatting.
7+
Indentation as a string or number of spaces. Pass in `undefined` for no formatting.
98
109
@default '\t'
1110
*/
12-
readonly indent?: string | number | null;
11+
readonly indent?: string | number | undefined;
1312

1413
/**
1514
Detect indentation automatically if the file exists.
@@ -28,7 +27,7 @@ declare namespace writeJsonFile {
2827
/**
2928
Passed into `JSON.stringify`.
3029
*/
31-
readonly replacer?: Replacer | Array<number | string>;
30+
readonly replacer?: Replacer | ReadonlyArray<number | string>;
3231

3332
/**
3433
Mode used when writing the file.
@@ -55,8 +54,8 @@ declare const writeJsonFile: {
5554
```
5655
*/
5756
(
58-
filepath: string,
59-
data: writeJsonFile.JSONStringifyable,
57+
filePath: string,
58+
data: unknown,
6059
options?: writeJsonFile.Options
6160
): Promise<void>;
6261

@@ -73,13 +72,10 @@ declare const writeJsonFile: {
7372
```
7473
*/
7574
sync(
76-
filepath: string,
77-
data: writeJsonFile.JSONStringifyable,
75+
filePath: string,
76+
data: unknown,
7877
options?: writeJsonFile.Options
7978
): void;
80-
81-
// TODO: Remove this for the next major release
82-
default: typeof writeJsonFile;
8379
};
8480

8581
export = writeJsonFile;

index.js

+26-18
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
'use strict';
2+
const {promisify} = require('util');
23
const path = require('path');
34
const fs = require('graceful-fs');
45
const writeFileAtomic = require('write-file-atomic');
56
const sortKeys = require('sort-keys');
67
const makeDir = require('make-dir');
7-
const pify = require('pify');
88
const detectIndent = require('detect-indent');
99

10+
const readFile = promisify(fs.readFile);
11+
const writeFileAtomicP = promisify(writeFileAtomic);
12+
1013
const init = (fn, filePath, data, options) => {
1114
if (!filePath) {
1215
throw new TypeError('Expected a filepath');
@@ -16,10 +19,11 @@ const init = (fn, filePath, data, options) => {
1619
throw new TypeError('Expected data to stringify');
1720
}
1821

19-
options = Object.assign({
22+
options = {
2023
indent: '\t',
21-
sortKeys: false
22-
}, options);
24+
sortKeys: false,
25+
...options
26+
};
2327

2428
if (options.sortKeys) {
2529
data = sortKeys(data, {
@@ -31,16 +35,23 @@ const init = (fn, filePath, data, options) => {
3135
return fn(filePath, data, options);
3236
};
3337

34-
const readFile = filePath => pify(fs.readFile)(filePath, 'utf8').catch(() => {});
38+
const main = async (filePath, data, options) => {
39+
let {indent} = options;
40+
41+
if (options.detectIndent) {
42+
try {
43+
const file = await readFile(filePath, 'utf8');
44+
indent = detectIndent(file).indent;
45+
} catch (error) {
46+
if (error.code !== 'ENOENT') {
47+
throw error;
48+
}
49+
}
50+
}
3551

36-
const main = (filePath, data, options) => {
37-
return (options.detectIndent ? readFile(filePath) : Promise.resolve())
38-
.then(string => {
39-
const indent = string ? detectIndent(string).indent : options.indent;
40-
const json = JSON.stringify(data, options.replacer, indent);
52+
const json = JSON.stringify(data, options.replacer, indent);
4153

42-
return pify(writeFileAtomic)(filePath, `${json}\n`, {mode: options.mode});
43-
});
54+
return writeFileAtomicP(filePath, `${json}\n`, {mode: options.mode});
4455
};
4556

4657
const mainSync = (filePath, data, options) => {
@@ -62,14 +73,11 @@ const mainSync = (filePath, data, options) => {
6273
return writeFileAtomic.sync(filePath, `${json}\n`, {mode: options.mode});
6374
};
6475

65-
const writeJsonFile = (filePath, data, options) => {
66-
return makeDir(path.dirname(filePath), {fs})
67-
.then(() => init(main, filePath, data, options));
76+
module.exports = async (filePath, data, options) => {
77+
await makeDir(path.dirname(filePath), {fs});
78+
return init(main, filePath, data, options);
6879
};
6980

70-
module.exports = writeJsonFile;
71-
// TODO: Remove this for the next major release
72-
module.exports.default = writeJsonFile;
7381
module.exports.sync = (filePath, data, options) => {
7482
makeDir.sync(path.dirname(filePath), {fs});
7583
init(mainSync, filePath, data, options);

index.test-d.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
import {expectType} from 'tsd';
22
import writeJsonFile = require('.');
3-
import {sync, Replacer, SortKeys, JSONStringifyable} from '.';
4-
5-
expectType<JSONStringifyable>('🦄');
6-
expectType<JSONStringifyable>(1);
7-
expectType<JSONStringifyable>(true);
8-
expectType<JSONStringifyable>(new Date());
9-
expectType<JSONStringifyable>(['hello', 'world']);
10-
expectType<JSONStringifyable>({unicorn: '🦄'});
3+
import {sync, Replacer, SortKeys} from '.';
114

125
expectType<SortKeys>(() => 1);
136
expectType<SortKeys>((a: string) => a.length);

package.json

+6-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"url": "sindresorhus.com"
1111
},
1212
"engines": {
13-
"node": ">=6"
13+
"node": ">=8"
1414
},
1515
"scripts": {
1616
"test": "xo && ava && tsd"
@@ -34,17 +34,16 @@
3434
"atomically"
3535
],
3636
"dependencies": {
37-
"detect-indent": "^5.0.0",
37+
"detect-indent": "^6.0.0",
3838
"graceful-fs": "^4.1.15",
39-
"make-dir": "^2.1.0",
40-
"pify": "^4.0.1",
41-
"sort-keys": "^2.0.0",
39+
"make-dir": "^3.0.0",
40+
"sort-keys": "^3.0.0",
4241
"write-file-atomic": "^2.4.2"
4342
},
4443
"devDependencies": {
4544
"ava": "^1.4.1",
46-
"tempfile": "^2.0.0",
47-
"tsd": "^0.7.2",
45+
"tempy": "^0.3.0",
46+
"tsd": "^0.7.3",
4847
"xo": "^0.24.0"
4948
}
5049
}

readme.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,16 @@ Returns a `Promise`.
3333

3434
#### options
3535

36-
Type: `Object`
36+
Type: `object`
3737

3838
##### indent
3939

40-
Type: `string` `number`<br>
40+
Type: `string | number`<br>
4141
Default: `'\t'`
4242

43-
Indentation as a string or number of spaces.<br>
44-
Pass in `null` for no formatting.
43+
Indentation as a string or number of spaces.
44+
45+
Pass in `undefined` for no formatting.
4546

4647
##### detectIndent
4748

@@ -52,7 +53,7 @@ Detect indentation automatically if the file exists.
5253

5354
##### sortKeys
5455

55-
Type: `boolean` `Function`<br>
56+
Type: `boolean | Function`<br>
5657
Default: `false`
5758

5859
Sort the keys recursively.<br>

test.js

+31-32
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,60 @@
1-
import path from 'path';
21
import fs from 'fs';
32
import test from 'ava';
4-
import tempfile from 'tempfile';
5-
import m from '.';
3+
import tempy from 'tempy';
4+
import writeJsonFile from '.';
65

76
test('async', async t => {
8-
const tmp = path.join(tempfile(), 'foo');
9-
await m(tmp, {foo: true}, {indent: 2});
10-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n "foo": true\n}\n');
7+
const tempFile = tempy.file();
8+
await writeJsonFile(tempFile, {foo: true}, {indent: 2});
9+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n "foo": true\n}\n');
1110
});
1211

1312
test('sync', t => {
14-
const tmp = path.join(tempfile(), 'foo');
15-
m.sync(tmp, {foo: true}, {detectIndent: true, indent: 2});
16-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n "foo": true\n}\n');
13+
const tempFile = tempy.file();
14+
writeJsonFile.sync(tempFile, {foo: true}, {detectIndent: true, indent: 2});
15+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n "foo": true\n}\n');
1716
});
1817

1918
test('detect indent', async t => {
20-
const tmp = path.join(tempfile(), 'foo');
21-
await m(tmp, {foo: true}, {indent: 2});
22-
await m(tmp, {foo: true, bar: true, foobar: true}, {detectIndent: true});
23-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n "foo": true,\n "bar": true,\n "foobar": true\n}\n');
19+
const tempFile = tempy.file();
20+
await writeJsonFile(tempFile, {foo: true}, {indent: 2});
21+
await writeJsonFile(tempFile, {foo: true, bar: true, foobar: true}, {detectIndent: true});
22+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n "foo": true,\n "bar": true,\n "foobar": true\n}\n');
2423
});
2524

2625
test('detect indent synchronously', t => {
27-
const tmp = path.join(tempfile(), 'foo');
28-
m.sync(tmp, {foo: true}, {indent: 2});
29-
m.sync(tmp, {foo: true, bar: true, foobar: true}, {detectIndent: true});
30-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n "foo": true,\n "bar": true,\n "foobar": true\n}\n');
26+
const tempFile = tempy.file();
27+
writeJsonFile.sync(tempFile, {foo: true}, {indent: 2});
28+
writeJsonFile.sync(tempFile, {foo: true, bar: true, foobar: true}, {detectIndent: true});
29+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n "foo": true,\n "bar": true,\n "foobar": true\n}\n');
3130
});
3231

3332
test('fall back to default indent if file doesn\'t exist', async t => {
34-
const tmp = path.join(tempfile(), 'foo');
35-
await m(tmp, {foo: true, bar: true, foobar: true}, {detectIndent: true});
36-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n\t"foo": true,\n\t"bar": true,\n\t"foobar": true\n}\n');
33+
const tempFile = tempy.file();
34+
await writeJsonFile(tempFile, {foo: true, bar: true, foobar: true}, {detectIndent: true});
35+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n\t"foo": true,\n\t"bar": true,\n\t"foobar": true\n}\n');
3736
});
3837

3938
test('async - {sortKeys: true}', async t => {
40-
const tmp = path.join(tempfile(), 'foo');
41-
await m(tmp, {c: true, b: true, a: true}, {sortKeys: true});
42-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n\t"a": true,\n\t"b": true,\n\t"c": true\n}\n');
39+
const tempFile = tempy.file();
40+
await writeJsonFile(tempFile, {c: true, b: true, a: true}, {sortKeys: true});
41+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n\t"a": true,\n\t"b": true,\n\t"c": true\n}\n');
4342
});
4443

4544
test('async - {sortKeys: false}', async t => {
46-
const tmp = path.join(tempfile(), 'foo');
47-
await m(tmp, {c: true, b: true, a: true}, {sortKeys: false});
48-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n\t"c": true,\n\t"b": true,\n\t"a": true\n}\n');
45+
const tempFile = tempy.file();
46+
await writeJsonFile(tempFile, {c: true, b: true, a: true}, {sortKeys: false});
47+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n\t"c": true,\n\t"b": true,\n\t"a": true\n}\n');
4948
});
5049

5150
test('async - `replacer` option', async t => {
52-
const tmp = path.join(tempfile(), 'foo');
53-
await m(tmp, {foo: true, bar: true}, {replacer: ['foo']});
54-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n\t"foo": true\n}\n');
51+
const tempFile = tempy.file();
52+
await writeJsonFile(tempFile, {foo: true, bar: true}, {replacer: ['foo']});
53+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n\t"foo": true\n}\n');
5554
});
5655

5756
test('sync - `replacer` option', t => {
58-
const tmp = path.join(tempfile(), 'foo');
59-
m.sync(tmp, {foo: true, bar: true}, {replacer: ['foo']});
60-
t.is(fs.readFileSync(tmp, 'utf8'), '{\n\t"foo": true\n}\n');
57+
const tempFile = tempy.file();
58+
writeJsonFile.sync(tempFile, {foo: true, bar: true}, {replacer: ['foo']});
59+
t.is(fs.readFileSync(tempFile, 'utf8'), '{\n\t"foo": true\n}\n');
6160
});

0 commit comments

Comments
 (0)