This repository has been archived by the owner on Jun 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Bootstrap.js
180 lines (158 loc) · 4.71 KB
/
Bootstrap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import $Helper from 'ima-helpers';
import ns from './namespace';
import ObjectContainer from './ObjectContainer';
import Router from './router/Router';
ns.namespace('ima');
/**
* Environment name value in the production environment.
*
* @const
* @type {string}
*/
const PRODUCTION_ENVIRONMENT = 'prod';
/**
* Application bootstrap used to initialize the environment and the application
* itself.
*/
export default class Bootstrap {
/**
* Initializes the bootstrap.
*
* @param {ObjectContainer} oc The application's object container to use
* for managing dependencies.
*/
constructor(oc) {
/**
* The object container used to manage dependencies.
*
* @type {ObjectContainer}
*/
this._oc = oc;
/**
* Application configuration.
*
* @type {Object<string, *>}
*/
this._config = {};
}
/**
* Initializes the application by running the bootstrap sequence. The
* sequence initializes the components of the application in the following
* order:
* - application settings
* - constants, service providers and class dependencies configuration
* - services
* - UI components
* - routing
*
* @param {Object<string, *>} config The application environment
* configuration for the current environment.
*/
run(config) {
this._config = config;
this._initSettings();
this._bindDependencies();
this._initServices();
this._initRoutes();
}
/**
* Initializes the application settings. The method loads the settings for
* all environments and then pics the settings for the current environment.
*
* The method also handles using the values in the production environment
* as default values for configuration items in other environments.
*/
_initSettings() {
let currentApplicationSettings = {};
let plugins = this._config.plugins.concat([
{ name: ObjectContainer.APP_BINDING_STATE, module: this._config }
]);
plugins
.filter(plugin => typeof plugin.module.initSettings === 'function')
.forEach(plugin => {
let allPluginSettings = plugin.module.initSettings(
ns,
this._oc,
this._config.settings
);
let environmentPluginSetting = $Helper.resolveEnvironmentSetting(
allPluginSettings,
this._config.settings.$Env
);
$Helper.assignRecursivelyWithTracking(plugin.name)(
currentApplicationSettings,
environmentPluginSetting
);
});
this._config.bind = Object.assign(
this._config.bind || {},
currentApplicationSettings,
this._config.settings
);
}
/**
* Returns setting for current environment where base values are from production
* environment and other environments override base values.
*
* @return {Object<string, *>}
*/
_getEnvironmentSetting(allSettings) {
let environment = this._config.settings.$Env;
let environmentSetting = allSettings[environment] || {};
if (environment !== PRODUCTION_ENVIRONMENT) {
let productionSettings = allSettings[PRODUCTION_ENVIRONMENT];
$Helper.assignRecursively(productionSettings, environmentSetting);
environmentSetting = productionSettings;
}
return environmentSetting;
}
/**
* Binds the constants, service providers and class dependencies to the
* object container.
*/
_bindDependencies() {
this._oc.setBindingState(ObjectContainer.IMA_BINDING_STATE);
this._config.initBindIma(
ns,
this._oc,
this._config.bind,
ObjectContainer.IMA_BINDING_STATE
);
this._config.plugins
.filter(plugin => typeof plugin.module.initBind === 'function')
.forEach(plugin => {
this._oc.setBindingState(
ObjectContainer.PLUGIN_BINDING_STATE,
plugin.name
);
plugin.module.initBind(ns, this._oc, this._config.bind, plugin.name);
});
this._oc.setBindingState(ObjectContainer.APP_BINDING_STATE);
this._config.initBindApp(
ns,
this._oc,
this._config.bind,
ObjectContainer.APP_BINDING_STATE
);
}
/**
* Initializes the routes.
*/
_initRoutes() {
let router = this._oc.get(Router);
this._config.initRoutes(ns, this._oc, this._config.routes, router);
}
/**
* Initializes the basic application services.
*/
_initServices() {
this._config.initServicesIma(ns, this._oc, this._config.services);
this._config.plugins
.filter(plugin => typeof plugin.module.initServices === 'function')
.forEach(plugin => {
plugin.module.initServices(ns, this._oc, this._config.services);
});
this._config.initServicesApp(ns, this._oc, this._config.services);
}
}
ns.ima.Bootstrap = Bootstrap;