UNPKG

3.16 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 this.name = this.name || process.env.NODE_ENV;
21 }
22
23 get (key, defaults) {
24 return NestedHelper.get(key, this._data, defaults);
25 }
26
27 getTitle () {
28 return this._names.join('.') || (this.original && this.original.getTitle());
29 }
30
31 includes (key, value) {
32 return NestedHelper.includes(value, key, this._data);
33 }
34
35 mergeWithParents (key) {
36 return this.parent ? {...this.parent.mergeWithParents(key), ...this.get(key)} : this.get(key);
37 }
38
39 deepMergeWithParents (key) {
40 return this.parent
41 ? ArrayHelper.deepAssign({}, this.parent.deepMergeWithParents(key), this.get(key))
42 : this.get(key);
43 }
44
45 async load () {
46 if (!this.loadByName(this.name)) {
47 this.loadByName('default');
48 }
49 this._sources.push({});
50 this._data = AssignHelper.deepAssign(...this._sources.reverse());
51 if (this.original) {
52 if (!this._names.includes(this.original.name)) {
53 this._names.unshift(this.original.name);
54 }
55 this._data = AssignHelper.deepAssign({}, this.original._data, this._data);
56 }
57 AssignHelper.deepAssign(this._data, this.data);
58 }
59
60 loadByName (name) {
61 if (this._names.includes(name)) {
62 throw new Error(`Configuration already loaded: ${name}`);
63 }
64 const data = this.readFiles(name);
65 if (data) {
66 this._sources.push(data);
67 this._names.push(name);
68 if (data.parent) { // local parent file
69 this.loadByName(data.parent);
70 }
71 return true;
72 }
73 }
74
75 readFiles (name) {
76 const base = this.readFile(name);
77 if (base) {
78 return AssignHelper.deepAssign(base, this.readFile(`${name}.local`));
79 }
80 }
81
82 readFile (name) {
83 const file = path.join(this.directory, `${name}.js`);
84 return fs.existsSync(file) ? require(file) : null;
85 }
86
87 deepAssign (data) {
88 AssignHelper.deepAssign(this._data, data);
89 }
90
91 inheritUndefined (keys) {
92 if (this.parent) {
93 for (const key of keys) {
94 this.deepAssignUndefinedByKey(key, this.parent.get(key));
95 }
96 }
97 }
98
99 deepAssignUndefinedByKey (key, data) {
100 let value = this.get(key);
101 if (!(value instanceof Object)) {
102 value = {};
103 NestedHelper.set(value, key, this._data);
104 }
105 AssignHelper.deepAssignUndefined(value, data);
106 }
107};
108
109const fs = require('fs');
110const path = require('path');
111const AssignHelper = require('../helper/AssignHelper');
112const NestedHelper = require('../helper/NestedHelper');
\No newline at end of file