UNPKG

4.25 kBJavaScriptView Raw
1/*───────────────────────────────────────────────────────────────────────────*\
2 │ Copyright (C) 2016 PayPal │
3 │ │
4 │ Licensed under the Apache License, Version 2.0 (the "License"); │
5 │ you may not use this file except in compliance with the License. │
6 │ You may obtain a copy of the License at │
7 │ │
8 │ http://www.apache.org/licenses/LICENSE-2.0 │
9 │ │
10 │ Unless required by applicable law or agreed to in writing, software │
11 │ distributed under the License is distributed on an "AS IS" BASIS, │
12 │ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
13 │ See the License for the specific language governing permissions and │
14 │ limitations under the License. │
15 \*───────────────────────────────────────────────────────────────────────────*/
16import Path from 'path';
17import shush from 'shush';
18import debuglog from 'debuglog';
19import Thing from 'core-util-is';
20import Config from './config';
21import Common from './common';
22import Handlers from './handlers';
23import Provider from './provider';
24
25
26const debug = debuglog('confit');
27
28export default class Factory {
29
30 constructor({ basedir, protocols = {}, defaults = 'config.json', envignore = []}) {
31 this.envignore = envignore.push('env');
32 this.basedir = basedir;
33 this.protocols = protocols;
34 this.promise = Promise.resolve({})
35 .then(store => Common.merge(Provider.convenience(), store))
36 .then(Factory.conditional(store => {
37 let file = Path.join(this.basedir, defaults);
38 return Handlers.resolveImport(shush(file), this.basedir)
39 .then(data => Common.merge(data, store));
40 }))
41 .then(Factory.conditional(store => {
42 let file = Path.join(this.basedir, `${store.env.env}.json`);
43 return Handlers.resolveImport(shush(file), this.basedir)
44 .then(data => Common.merge(shush(file), store));
45 }))
46 .then(store => Common.merge(Provider.env(envignore), store))
47 .then(store => Common.merge(Provider.argv(), store));
48 }
49
50 addDefault(obj) {
51 this._add(obj, (store, data) => Common.merge(store, data));
52 return this;
53 }
54
55 addOverride(obj) {
56 this._add(obj, (store, data) => Common.merge(data, store));
57 return this;
58 }
59
60 create(cb) {
61 this.promise
62 .then(store => Handlers.resolveImport(store, this.basedir))
63 .then(store => Handlers.resolveCustom(store, this.protocols))
64 .then(store => Handlers.resolveConfig(store))
65 .then(store => cb(null, new Config(store)), cb);
66 }
67
68 _add(obj, fn) {
69 let data = this._resolveFile(obj);
70 let handler = Handlers.resolveImport(data, this.basedir);
71 this.promise = this.promise.then(store => handler.then(data => fn(store, data)));
72 }
73
74 _resolveFile(path) {
75 if (Thing.isString(path)) {
76 let file = Common.isAbsolute(path) ? path : Path.join(this.basedir, path);
77 return shush(file);
78 }
79 return path;
80 }
81
82 static conditional(fn) {
83 return function (store) {
84 try {
85 return fn(store);
86 } catch (err) {
87 if (err.code && err.code === 'MODULE_NOT_FOUND') {
88 debug(`WARNING: ${err.message}`);
89 return store;
90 }
91 throw err;
92 }
93 }
94 }
95
96}