@slimio/config
Advanced tools
Comparing version 0.0.1 to 0.1.0
@@ -0,0 +0,0 @@ /// <reference types="node" /> |
@@ -10,3 +10,5 @@ { | ||
"include": [ | ||
"index.js" | ||
"index.js", | ||
"src/config.class.js", | ||
"src/utils.js" | ||
], | ||
@@ -13,0 +15,0 @@ "exclude": [ |
{ | ||
"name": "@slimio/config", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "SlimIO Reactive JSON Config loaded", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "npx ava --verbose" | ||
"test": "npx ava --verbose", | ||
"doc": "npx jsdoc -c ./jsdoc.json -r", | ||
"coverage": "npx nyc ava", | ||
"report": "npx nyc report --reporter=html" | ||
}, | ||
@@ -14,3 +17,3 @@ "repository": { | ||
"engines": { | ||
"node": ">=8.11.1" | ||
"node": ">=8.11.1" | ||
}, | ||
@@ -31,4 +34,5 @@ "keywords": [ | ||
"@escommunity/minami": "^1.0.0", | ||
"@slimio/eslint-config": "^1.0.1", | ||
"@slimio/eslint-config": "^1.1.3", | ||
"ava": "^0.25.0", | ||
"eslint": "^4.19.1", | ||
"nyc": "^11.6.0" | ||
@@ -35,0 +39,0 @@ }, |
# Config | ||
SlimIO - Reactive JSON Config loader | ||
## Features | ||
- Hot-reloading of configuration | ||
- Reactive with observable key(s) | ||
- Safe with JSON Schema validation | ||
## Getting Started | ||
This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com). | ||
```bash | ||
$ npm i @slimio/config | ||
# or | ||
$ yarn add @slimio/config | ||
``` | ||
Create a simple config file for your project (take this example) | ||
```json | ||
{ | ||
"loglevel": 5, | ||
"logsize": 4048, | ||
"login": "administrator" | ||
} | ||
``` | ||
Install and use our package like this to recover values (with commonjs). | ||
```js | ||
const Config = require("@slimio/config"); | ||
async function main() { | ||
const myConfig = new Config("./path/to/config.json"); | ||
await myConfig.read(); | ||
console.log(myConfig.get("loglevel")); | ||
} | ||
main().catch(console.error); | ||
``` |
@@ -51,2 +51,5 @@ // Require Node.JS core packages | ||
* @property {Object} defaultSchema | ||
* | ||
* @author Thomas GENTILHOMME <gentilhomme.thomas@gmail.com> | ||
* @version 0.1.0 | ||
*/ | ||
@@ -96,3 +99,3 @@ class Config extends Events { | ||
// Assign defaultSchema is exist! | ||
if (Reflect.has(options.defaultSchema)) { | ||
if (Reflect.has(options, "defaultSchema")) { | ||
this.defaultSchema = options.defaultSchema; | ||
@@ -106,2 +109,3 @@ } | ||
* @member {Object} payload | ||
* @desc Get a payload Object clone (or null if the configuration has not been read yet) | ||
*/ | ||
@@ -121,2 +125,3 @@ get payload() { | ||
* @param {!Object} newPayload Newest payload to setup | ||
* @desc Set a new payload Object | ||
* | ||
@@ -153,6 +158,20 @@ * @throws {Error} | ||
* @method read | ||
* @desc Read the configuration file | ||
* @desc Read the configuration file (And optionaly apply a default payload value if the file doesn't exist) | ||
* @memberof Config# | ||
* @param {T=} defaultPayload Optional default payload (if the file doesn't exist on the disk). | ||
* @return {Promise<this>} | ||
* | ||
* @example | ||
* const myConfig = new Config("./path/to/config.json", { | ||
* autoReload: true, | ||
* createOnNoEntry: true | ||
* }); | ||
* | ||
* async function main() { | ||
* await myConfig.read({ | ||
* foo: "bar" | ||
* }); | ||
* console.log(myConfig.payload); | ||
* } | ||
* main().catch(console.error); | ||
*/ | ||
@@ -215,7 +234,15 @@ async read(defaultPayload) { | ||
* @return {void} | ||
* | ||
* @throws {Error} | ||
*/ | ||
setupAutoReload() { | ||
if (!this.configHasBeenRead || this.autoReloadActivated) { | ||
if (!this.configHasBeenRead) { | ||
throw new Error( | ||
"Config.setupAutoReaload - cannot setup autoReload when the config has not been read yet!" | ||
); | ||
} | ||
if (this.autoReloadActivated) { | ||
return; | ||
} | ||
this.autoReloadActivated = true; | ||
@@ -239,2 +266,15 @@ this.watcher = watcher(this.configFile, { delay: this.reloadDelay }, async(evt, name) => { | ||
* @throws {TypeError} | ||
* | ||
* @example | ||
* const myConfig = new Config("./path/to/config.json", { | ||
* createOnNoEntry: true | ||
* }); | ||
* | ||
* async function main() { | ||
* await myConfig.read({ | ||
* foo: "bar" | ||
* }); | ||
* const value = myConfig.get("path.to.key"); | ||
* } | ||
* main().catch(console.error); | ||
*/ | ||
@@ -261,2 +301,28 @@ get(fieldPath) { | ||
* @return {Observable} | ||
* | ||
* @example | ||
* const myConfig = new Config("./config.json", { | ||
* autoReload: true, | ||
* createOnNoEntry: true | ||
* }); | ||
* const { writeFile } = require("fs"); | ||
* const { promisify } = require("util"); | ||
* | ||
* // Promisify fs.writeFile | ||
* const asyncwriteFile = promisify(writeFile); | ||
* | ||
* async function main() { | ||
* await myConfig.read({ | ||
* foo: "bar" | ||
* }); | ||
* | ||
* // Observe initial and futur value(s) of foo | ||
* myConfig.observableOf("foo").subscribe(console.log); | ||
* | ||
* // Re-write local config file | ||
* await asyncwriteFile("./config.json", JSON.stringify( | ||
* { foo: "world!" }, null, 4 | ||
* )); | ||
* } | ||
* main().catch(console.error); | ||
*/ | ||
@@ -275,4 +341,4 @@ observableOf(fieldPath) { | ||
* @template H | ||
* @method get | ||
* @desc Get a given field of the configuration | ||
* @method set | ||
* @desc Set a field in the configuration | ||
* @memberof Config# | ||
@@ -285,2 +351,21 @@ * @param {!String} fieldPath Path to the field (separated with dot) | ||
* @throws {TypeError} | ||
* | ||
* @example | ||
* const myConfig = new Config("./config.json", { | ||
* createOnNoEntry: true, | ||
* // writeOnSet: true | ||
* }); | ||
* | ||
* async function main() { | ||
* await myConfig.read({ | ||
* foo: "bar" | ||
* }); | ||
* | ||
* // Set a new value for foo | ||
* myConfig.set("foo", "hello world!"); | ||
* | ||
* // Write on disk the configuration | ||
* await myConfig.writeOnDisk(); | ||
* } | ||
* main().catch(console.error); | ||
*/ | ||
@@ -290,7 +375,7 @@ set(fieldPath, fieldValue) { | ||
throw new Error( | ||
"Config.get - Unable to set a key, the configuration has not been initialized yet!" | ||
"Config.set - Unable to set a key, the configuration has not been initialized yet!" | ||
); | ||
} | ||
if (is(fieldPath) !== "string") { | ||
throw new TypeError("Config.get->fieldPath should be typeof <string>"); | ||
throw new TypeError("Config.set->fieldPath should be typeof <string>"); | ||
} | ||
@@ -317,8 +402,2 @@ | ||
} | ||
if (this[schema](this[payload]) === false) { | ||
const errors = formatAjvErrors(this[schema].errors); | ||
throw new Error( | ||
`Config.writeOnDisk - Cannot write on the disk invalid config, err => ${errors}` | ||
); | ||
} | ||
@@ -332,3 +411,3 @@ await FSAsync.access(this.configFile, W_OK); | ||
* @method close | ||
* @desc Close the configuration | ||
* @desc Close the configuration (it will close the watcher and all active observers). | ||
* @memberof Config# | ||
@@ -338,2 +417,7 @@ * @returns {Promise<void>} | ||
async close() { | ||
if (!this.configHasBeenRead) { | ||
throw new Error( | ||
"Config.close - Cannot close unreaded configuration" | ||
); | ||
} | ||
if (this.autoReloadActivated && !this.watcher.isClosed()) { | ||
@@ -343,2 +427,3 @@ this.watcher.close(); | ||
} | ||
await this.writeOnDisk(); | ||
@@ -345,0 +430,0 @@ for (const [, subscriptionObservers] of this.subscriptionObservers) { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
0
1379
43
150389
5
22
2