UNPKG

9.84 kBMarkdownView Raw
1# conf [![Build Status](https://travis-ci.org/sindresorhus/conf.svg?branch=master)](https://travis-ci.org/sindresorhus/conf)
2
3> Simple config handling for your app or module
4
5All you have to care about is what to persist. This module will handle all the dull details like where and how.
6
7*If you need this for Electron, check out [`electron-store`](https://github.com/sindresorhus/electron-store) instead.*
8
9
10## Install
11
12```
13$ npm install conf
14```
15
16
17## Usage
18
19```js
20const Conf = require('conf');
21
22const config = new Conf();
23
24config.set('unicorn', '🦄');
25console.log(config.get('unicorn'));
26//=> '🦄'
27
28// Use dot-notation to access nested properties
29config.set('foo.bar', true);
30console.log(config.get('foo'));
31//=> {bar: true}
32
33config.delete('unicorn');
34console.log(config.get('unicorn'));
35//=> undefined
36```
37
38Or [create a subclass](https://github.com/sindresorhus/electron-store/blob/master/index.js).
39
40
41## API
42
43Changes are written to disk atomically, so if the process crashes during a write, it will not corrupt the existing config.
44
45### Conf([options])
46
47Returns a new instance.
48
49### options
50
51Type: `Object`
52
53#### defaults
54
55Type: `Object`
56
57Default values for the config items.
58
59**Note:** The values in `defaults` will overwrite the `default` key in the `schema` option.
60
61#### schema
62
63Type: `Object`
64
65[JSON Schema](https://json-schema.org) to validate your config data.
66
67Under the hood, the JSON Schema validator [ajv](https://github.com/epoberezkin/ajv) is used to validate your config. We use [JSON Schema draft-07](http://json-schema.org/latest/json-schema-validation.html) and support all [validation keywords](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md) and [formats](https://github.com/epoberezkin/ajv#formats).
68
69You should define your schema as an object where each key is the name of your data's property and each value is a JSON schema used to validate that property. See more [here](https://json-schema.org/understanding-json-schema/reference/object.html#properties).
70
71Example:
72
73```js
74const Conf = require('conf');
75
76const schema = {
77 foo: {
78 type: 'number',
79 maximum: 100,
80 minimum: 1,
81 default: 50
82 },
83 bar: {
84 type: 'string',
85 format: 'url'
86 }
87};
88
89const config = new Conf({schema});
90
91console.log(config.get('foo'));
92//=> 50
93
94config.set('foo', '1');
95// [Error: Config schema violation: `foo` should be number]
96```
97
98**Note:** The `default` value will be overwritten by the `defaults` option if set.
99
100#### configName
101
102Type: `string`<br>
103Default: `config`
104
105Name of the config file (without extension).
106
107Useful if you need multiple config files for your app or module. For example, different config files between two major versions.
108
109#### projectName
110
111Type: `string`<br>
112Default: The `name` field in the package.json closest to where `conf` is imported.
113
114You only need to specify this if you don't have a package.json file in your project.
115
116#### cwd
117
118Type: `string`<br>
119Default: System default [user config directory](https://github.com/sindresorhus/env-paths#pathsconfig)
120
121**You most likely don't need this. Please don't use it unless you really have to.**
122
123Overrides `projectName`.
124
125The only use-case I can think of is having the config located in the app directory or on some external storage.
126
127#### encryptionKey
128
129Type: `string` `Buffer` `TypedArray` `DataView`<br>
130Default: `undefined`
131
132This can be used to secure sensitive data **if** the encryption key is stored in a secure manner (not plain-text) in the Node.js app. For example, by using [`node-keytar`](https://github.com/atom/node-keytar) to store the encryption key securely, or asking the encryption key from the user (a password) and then storing it in a variable.
133
134In addition to security, this could be used for obscurity. If a user looks through the config directory and finds the config file, since it's just a JSON file, they may be tempted to modify it. By providing an encryption key, the file will be obfuscated, which should hopefully deter any users from doing so.
135
136It also has the added bonus of ensuring the config file's integrity. If the file is changed in any way, the decryption will not work, in which case the store will just reset back to its default state.
137
138When specified, the store will be encrypted using the [`aes-256-cbc`](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) encryption algorithm.
139
140#### fileExtension
141
142Type: `string`<br>
143Default: `json`
144
145Extension of the config file.
146
147You would usually not need this, but could be useful if you want to interact with a file with a custom file extension that can be associated with your app. These might be simple save/export/preference files that are intended to be shareable or saved outside of the app.
148
149#### clearInvalidConfig
150
151Type: `boolean`<br>
152Default: `true`
153
154The config is cleared if reading the config file causes a `SyntaxError`. This is a good default, as the config file is not intended to be hand-edited, so it usually means the config is corrupt and there's nothing the user can do about it anyway. However, if you let the user edit the config file directly, mistakes might happen and it could be more useful to throw an error when the config is invalid instead of clearing. Disabling this option will make it throw a `SyntaxError` on invalid config instead of clearing.
155
156#### serialize
157
158Type: `Function`<br>
159Default: `value => JSON.stringify(value, null, '\t')`
160
161Function to serialize the config object to a UTF-8 string when writing the config file.
162
163You would usually not need this, but it could be useful if you want to use a format other than JSON.
164
165#### deserialize
166
167Type: `Function`<br>
168Default: `JSON.parse`
169
170Function to deserialize the config object from a UTF-8 string when reading the config file.
171
172You would usually not need this, but it could be useful if you want to use a format other than JSON.
173
174#### projectSuffix
175
176Type: `string`<br>
177Default: `nodejs`
178
179**You most likely don't need this. Please don't use it unless you really have to.**
180
181Suffix appended to `projectName` during config file creation to avoid name conflicts with native apps.
182
183You can pass an empty string to remove the suffix.
184
185For example, on macOS, the config file will be stored in the `~/Library/Preferences/foo-nodejs` directory, where `foo` is the `projectName`.
186
187#### accessPropertiesByDotNotation
188
189Type: `boolean`<br>
190Default: `true`
191
192Accessing nested properties by dot notation. For example:
193
194```js
195const config = new Conf();
196
197config.set({
198 foo: {
199 bar: {
200 foobar: '🦄'
201 }
202 }
203});
204
205console.log(config.get('foo.bar.foobar'));
206//=> '🦄'
207```
208
209Alternatively, you can set this option to `false` so the whole string would be treated as one key.
210
211```js
212const config = new Conf({accessPropertiesByDotNotation: false});
213
214config.set({
215 `foo.bar.foobar`: '🦄'
216});
217
218console.log(config.get('foo.bar.foobar'));
219//=> '🦄'
220```
221
222### Instance
223
224You can use [dot-notation](https://github.com/sindresorhus/dot-prop) in a `key` to access nested properties.
225
226The instance is [`iterable`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols) so you can use it directly in a [`for…of`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/for...of) loop.
227
228#### .set(key, value)
229
230Set an item.
231
232The `value` must be JSON serializable. Trying to set the type `undefined`, `function`, or `symbol` will result in a TypeError.
233
234#### .set(object)
235
236Set multiple items at once.
237
238#### .get(key, [defaultValue])
239
240Get an item or `defaultValue` if the item does not exist.
241
242#### .has(key)
243
244Check if an item exists.
245
246#### .delete(key)
247
248Delete an item.
249
250#### .clear()
251
252Delete all items.
253
254#### .onDidChange(key, callback)
255
256`callback`: `(newValue, oldValue) => {}`
257
258Watches the given `key`, calling `callback` on any changes. When a key is first set `oldValue` will be `undefined`, and when a key is deleted `newValue` will be `undefined`.
259
260#### .onDidAnyChange(callback)
261
262`callback`: `(newValue, oldValue) => {}`
263
264Watches the whole config object, calling `callback` on any changes. `oldValue` and `newValue` will be the config object before and after the change, respectively. You must compare `oldValue` to `newValue` to find out what changed.
265
266#### .size
267
268Get the item count.
269
270#### .store
271
272Get all the config as an object or replace the current config with an object:
273
274```js
275conf.store = {
276 hello: 'world'
277};
278```
279
280#### .path
281
282Get the path to the config file.
283
284
285
286## FAQ
287
288### How is this different from [`configstore`](https://github.com/yeoman/configstore)?
289
290I'm also the author of `configstore`. While it's pretty good, I did make some mistakes early on that are hard to change at this point. This module is the result of everything I learned from making `configstore`. Mainly where the config is stored. In `configstore`, the config is stored in `~/.config` (which is mainly a Linux convention) on all systems, while `conf` stores config in the system default [user config directory](https://github.com/sindresorhus/env-paths#pathsconfig). The `~/.config` directory, it turns out, often have an incorrect permission on macOS and Windows, which has caused a lot of grief for users.
291
292### Can I use YAML or another serialization format?
293
294The `serialize` and `deserialize` options can be used to customize the format of the config file, as long as the representation is compatible with `utf8` encoding.
295
296Example using YAML:
297
298```js
299const Conf = require('conf');
300const yaml = require('js-yaml');
301
302const config = new Conf({
303 fileExtension: 'yaml',
304 serialize: yaml.safeDump,
305 deserialize: yaml.safeLoad
306});
307```
308
309
310## Related
311
312- [electron-store](https://github.com/sindresorhus/electron-store) - Simple data persistence for your Electron app or module
313- [cache-conf](https://github.com/SamVerschueren/cache-conf) - Simple cache config handling for your app or module
314
315
316## License
317
318MIT © [Sindre Sorhus](https://sindresorhus.com)