UNPKG

3.11 kBJavaScriptView Raw
1/**
2 * @copyright Copyright (c) 2019 Maxim Khorin <maksimovichu@gmail.com>
3 */
4'use strict';
5
6const Base = require('./Base');
7
8module.exports = class Configuration extends Base {
9
10 _names = [];
11 _sources = [];
12
13 constructor (config) {
14 super({
15 // directory: configuration directory,
16 // parent: parent configuration,
17 // original: original configuration,
18 ...config
19 });
20 }
21
22 get (key, defaults) {
23 return NestedHelper.get(key, this._data, defaults);
24 }
25
26 getTitle () {
27 return this._names.join('.') || (this.original && this.original.getTitle());
28 }
29
30 includes (key, value) {
31 return NestedHelper.includes(value, key, this._data);
32 }
33
34 mergeWithParents (key) {
35 return this.parent ? {...this.parent.mergeWithParents(key), ...this.get(key)} : this.get(key);
36 }
37
38 deepMergeWithParents (key) {
39 return this.parent
40 ? ArrayHelper.deepAssign({}, this.parent.deepMergeWithParents(key), this.get(key))
41 : this.get(key);
42 }
43
44 async load () {
45 if (!this.loadByName(this.name)) {
46 this.loadByName('default');
47 }
48 this._sources.push({});
49 this._data = AssignHelper.deepAssign(...this._sources.reverse());
50 if (this.original) {
51 if (!this._names.includes(this.original.name)) {
52 this._names.unshift(this.original.name);
53 }
54 this._data = AssignHelper.deepAssign({}, this.original._data, this._data);
55 }
56 AssignHelper.deepAssign(this._data, this.data);
57 }
58
59 loadByName (name) {
60 if (this._names.includes(name)) {
61 throw new Error(`Configuration already loaded: ${name}`);
62 }
63 const data = this.readFiles(name);
64 if (data) {
65 this._sources.push(data);
66 this._names.push(name);
67 if (data.parent) { // local parent file
68 this.loadByName(data.parent);
69 }
70 return true;
71 }
72 }
73
74 readFiles (name) {
75 const base = this.readFile(name);
76 if (base) {
77 return AssignHelper.deepAssign(base, this.readFile(`${name}.local`));
78 }
79 }
80
81 readFile (name) {
82 const file = path.join(this.directory, `${name}.js`);
83 return fs.existsSync(file) ? require(file) : null;
84 }
85
86 deepAssign (data) {
87 AssignHelper.deepAssign(this._data, data);
88 }
89
90 inheritUndefined (keys) {
91 if (this.parent) {
92 for (const key of keys) {
93 this.deepAssignUndefinedByKey(key, this.parent.get(key));
94 }
95 }
96 }
97
98 deepAssignUndefinedByKey (key, data) {
99 let value = this.get(key);
100 if (!(value instanceof Object)) {
101 value = {};
102 NestedHelper.set(value, key, this._data);
103 }
104 AssignHelper.deepAssignUndefined(value, data);
105 }
106};
107
108const fs = require('fs');
109const path = require('path');
110const AssignHelper = require('../helper/AssignHelper');
111const NestedHelper = require('../helper/NestedHelper');
\No newline at end of file