UNPKG

9.31 kBTypeScriptView Raw
1/// <reference types="node" resolution-mode="require"/>
2import { type JSONSchema as TypedJSONSchema } from 'json-schema-typed';
3import type Conf from './index.js';
4export type Options<T extends Record<string, any>> = {
5 /**
6 Config used if there are no existing config.
7
8 **Note:** The values in `defaults` will overwrite the `default` key in the `schema` option.
9 */
10 defaults?: Readonly<T>;
11 /**
12 [JSON Schema](https://json-schema.org) to validate your config data.
13
14 Under the hood, the JSON Schema validator [ajv](https://github.com/epoberezkin/ajv) is used to validate your config. We use [JSON Schema draft-07](https://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).
15
16 You 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).
17
18 @example
19 ```
20 import Conf from 'conf';
21
22 const schema = {
23 foo: {
24 type: 'number',
25 maximum: 100,
26 minimum: 1,
27 default: 50
28 },
29 bar: {
30 type: 'string',
31 format: 'url'
32 }
33 };
34
35 const config = new Conf({
36 projectName: 'foo',
37 schema
38 });
39
40 console.log(config.get('foo'));
41 //=> 50
42
43 config.set('foo', '1');
44 // [Error: Config schema violation: `foo` should be number]
45 ```
46
47 **Note:** The `default` value will be overwritten by the `defaults` option if set.
48 */
49 schema?: Schema<T>;
50 /**
51 Name of the config file (without extension).
52
53 Useful if you need multiple config files for your app or module. For example, different config files between two major versions.
54
55 @default 'config'
56 */
57 configName?: string;
58 /**
59 __Required unless you specify the `cwd` option.__
60
61 You can fetch the `name` field from package.json.
62 */
63 projectName?: string;
64 /**
65 __Required if you specify the `migration` option.__
66
67 You can fetch the `version` field from package.json.
68 */
69 projectVersion?: string;
70 /**
71 You can use migrations to perform operations to the store whenever a version is changed.
72
73 The `migrations` object should consist of a key-value pair of `'version': handler`. The `version` can also be a [semver range](https://github.com/npm/node-semver#ranges).
74
75 Note: The version the migrations use refers to the __project version__ by default. If you want to change this behavior, specify the `projectVersion` option.
76
77 @example
78 ```
79 import Conf from 'conf';
80
81 const store = new Conf({
82 projectName: 'foo',
83 projectVersion: …,
84 migrations: {
85 '0.0.1': store => {
86 store.set('debugPhase', true);
87 },
88 '1.0.0': store => {
89 store.delete('debugPhase');
90 store.set('phase', '1.0.0');
91 },
92 '1.0.2': store => {
93 store.set('phase', '1.0.2');
94 },
95 '>=2.0.0': store => {
96 store.set('phase', '>=2.0.0');
97 }
98 }
99 });
100 ```
101 */
102 migrations?: Migrations<T>;
103 /**
104 The given callback function will be called before each migration step.
105
106 This can be useful for logging purposes, preparing migration data, etc.
107 */
108 beforeEachMigration?: BeforeEachMigrationCallback<T>;
109 /**
110 __You most likely don't need this. Please don't use it unless you really have to.__
111
112 The only use-case I can think of is having the config located in the app directory or on some external storage. Default: System default user [config directory](https://github.com/sindresorhus/env-paths#pathsconfig).
113 */
114 cwd?: string;
115 /**
116 Note that this is __not intended for security purposes__, since the encryption key would be easily found inside a plain-text Node.js app.
117
118 Its main use is 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.
119
120 It 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.
121
122 When specified, the store will be encrypted using the [`aes-256-cbc`](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) encryption algorithm.
123 */
124 encryptionKey?: string | Uint8Array | NodeJS.TypedArray | DataView;
125 /**
126 Extension of the config file.
127
128 You 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.
129
130 @default 'json'
131 */
132 fileExtension?: string;
133 /**
134 The config is cleared if reading the config file causes a `SyntaxError`. This is a good behavior for unimportant data, 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.
135
136 @default false
137 */
138 clearInvalidConfig?: boolean;
139 /**
140 Function to serialize the config object to a UTF-8 string when writing the config file.
141
142 You would usually not need this, but it could be useful if you want to use a format other than JSON.
143
144 @default value => JSON.stringify(value, null, '\t')
145 */
146 readonly serialize?: Serialize<T>;
147 /**
148 Function to deserialize the config object from a UTF-8 string when reading the config file.
149
150 You would usually not need this, but it could be useful if you want to use a format other than JSON.
151
152 @default JSON.parse
153 */
154 readonly deserialize?: Deserialize<T>;
155 /**
156 __You most likely don't need this. Please don't use it unless you really have to.__
157
158 Suffix appended to `projectName` during config file creation to avoid name conflicts with native apps.
159
160 You can pass an empty string to remove the suffix.
161
162 For example, on macOS, the config file will be stored in the `~/Library/Preferences/foo-nodejs` directory, where `foo` is the `projectName`.
163
164 @default 'nodejs'
165 */
166 readonly projectSuffix?: string;
167 /**
168 Access nested properties by dot notation.
169
170 @default true
171
172 @example
173 ```
174 const config = new Conf({projectName: 'foo'});
175
176 config.set({
177 foo: {
178 bar: {
179 foobar: '🦄'
180 }
181 }
182 });
183
184 console.log(config.get('foo.bar.foobar'));
185 //=> '🦄'
186 ```
187
188 Alternatively, you can set this option to `false` so the whole string would be treated as one key.
189
190 @example
191 ```
192 const config = new Conf({
193 projectName: 'foo',
194 accessPropertiesByDotNotation: false
195 });
196
197 config.set({
198 `foo.bar.foobar`: '🦄'
199 });
200
201 console.log(config.get('foo.bar.foobar'));
202 //=> '🦄'
203 ```
204
205 */
206 readonly accessPropertiesByDotNotation?: boolean;
207 /**
208 Watch for any changes in the config file and call the callback for `onDidChange` or `onDidAnyChange` if set. This is useful if there are multiple processes changing the same config file.
209
210 @default false
211 */
212 readonly watch?: boolean;
213 /**
214 The [mode](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation) that will be used for the config file.
215
216 You would usually not need this, but it could be useful if you want to restrict the permissions of the config file. Setting a permission such as `0o600` would result in a config file that can only be accessed by the user running the program.
217
218 Note that setting restrictive permissions can cause problems if different users need to read the file. A common problem is a user running your tool with and without `sudo` and then not being able to access the config the second time.
219
220 @default 0o666
221 */
222 readonly configFileMode?: number;
223};
224export type Migrations<T extends Record<string, any>> = Record<string, (store: Conf<T>) => void>;
225export type BeforeEachMigrationContext = {
226 fromVersion: string;
227 toVersion: string;
228 finalVersion: string;
229 versions: string[];
230};
231export type BeforeEachMigrationCallback<T extends Record<string, any>> = (store: Conf<T>, context: BeforeEachMigrationContext) => void;
232export type Schema<T> = {
233 [Property in keyof T]: ValueSchema;
234};
235export type ValueSchema = TypedJSONSchema;
236export type Serialize<T> = (value: T) => string;
237export type Deserialize<T> = (text: string) => T;
238export type OnDidChangeCallback<T> = (newValue?: T, oldValue?: T) => void;
239export type OnDidAnyChangeCallback<T> = (newValue?: Readonly<T>, oldValue?: Readonly<T>) => void;
240export type Unsubscribe = () => void;