-
Notifications
You must be signed in to change notification settings - Fork 71
/
index.js
210 lines (198 loc) · 8.47 KB
/
index.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
// Strong globalize
const g = require('./lib/globalize');
const PluginBase = require('./lib/plugin-base');
const Bootstrapper = require('./lib/bootstrapper');
const addInstructionsToBrowserify = require('./lib/bundler');
/**
* Initialize an application from an options object or
* a set of JSON and JavaScript files.
*
* > **NOTE**: This module is primarily intended for use with LoopBack 2.0.
* It _does_ work with LoopBack 1.x applications, but
* none of the LoopBack 1.x examples or generated code (scaffolding) use it.
*
* This function takes an optional argument that is either a string
* or an object.
*
* If the argument is a string, then it sets the application root directory
* based on the string value. Then it:
*
* 1. Creates DataSources from the `datasources.json` file in the application
* root directory.
*
* 2. Configures Models from the `model-config.json` file in the application
* root directory.
*
* 3. Configures the LoopBack Application object from the `config.json` file
* in the application root directory. These properties can be accessed
* using `app.get('propname')`.
*
* If the argument is an object, then it looks for `models`, `dataSources`,
* 'config', `modelsRootDir`, `dsRootDir`, `appConfigRootDir` and `appRootDir`
* properties of the object.
*
* If the object has no `appRootDir` property then it sets the current working
* directory as the application root directory.
*
* The execution environment, {env}, is established from, in order,
* - `options.env`
* - `process.env.NODE_ENV`,
* - the literal `development`.
*
* Then it:
*
* 1. Creates DataSources from the `options.dataSources` object, if provided;
* otherwise, it searches for the files
* - `datasources.json`,
* - `datasources.local.js` or `datasources.local.json` (only one),
* - `datasources.{env}.js` or `datasources.{env}.json` (only one)
*
* in the directory designated by 'options.dsRootDir', if present, or the
* application root directory. It merges the data source definitions from
* the files found.
*
* 2. Creates Models from the `options.models` object, if provided;
* otherwise, it searches for the files
* - `model-config.json`,
* - `model-config.local.js` or `model-config.local.json` (only one),
* - `model-config.{env}.js` or `model-config.{env}.json` (only one)
*
* in the directory designated by 'options.modelsRootDir', if present, or
* the application root directory. It merges the model definitions from the
* files found.
*
* 3. Configures the Application object from the `options.config` object,
* if provided;
* otherwise, it searches for the files
* - `config.json`,
* - `config.local.js` or `config.local.json` (only one),
* - `config.{env}.js` or `config.{env}.json` (only one)
*
* in the directory designated by 'options.appConfigRootDir', if present, or
* the application root directory. It merges the properties from the files
* found.
*
* In both cases, the function loads JavaScript files in the
* `/boot` subdirectory of the application root directory with `require()`.
*
* **NOTE:** The version 2.0 of loopback-boot changed the way how models
* are created. The `model-config.json` file contains only configuration
* options like dataSource and extra relations. To define a model,
* create a per-model JSON file in `models/` directory.
*
* **NOTE:** Mixing `bootLoopBackApp(app, bootConfig)` and
* `app.model(name, modelConfig)` in multiple
* files may result in models being undefined due to race conditions.
* To avoid this when using `bootLoopBackApp()` make sure all models are passed
* as part of the `models` definition.
*
* Throws an error if the config object is not valid or if boot fails.
*
* @param app LoopBack application created by `loopback()`.
* @options {String|Object} options Boot options; If String, this is
* the application root directory; if object, has below properties.
* @property {String} [appRootDir] Directory to use when loading JSON and
* JavaScript files.
* Defaults to the current directory (`process.cwd()`).
* @property {String} [appConfigRootDir] Directory to use when loading
* `config.json`. Defaults to `appRootDir`.
* @property {Object} [models] Object containing `Model` configurations.
* @property {Array} [modelDefinitions] List of model definitions to use.
* When `options.modelDefinitions` is provided, loopback-boot does not
* search filesystem and use only the models provided in this argument.
* @property {Object} [dataSources] Object containing `DataSource` definitions.
* @property {String} [modelsRootDir] Directory to use when loading
* `model-config.json`. Defaults to `appRootDir`.
* @property {String} [dsRootDir] Directory to use when loading
* `datasources.json`. Defaults to `appRootDir`.
* @property {String} [middlewareRootDir] Directory to use when loading
* `middleware.json`. Defaults to `appRootDir`.
* @property {String} [componentRootDir] Directory to use when loading
* `component-config.json`. Defaults to `appRootDir`.
* @property {String} [env] Environment type, defaults to `process.env.NODE_ENV`
* or `development`. Common values are `development`, `staging` and
* `production`; however the applications are free to use any names.
* @property {Array.<String>} [modelSources] List of directories where to look
* for files containing model definitions.
* @property {Object} [middleware] Middleware configuration to use instead
* of `{appRootDir}/middleware.json`
* @property {Object} [components] Component configuration to use instead
* of `{appRootDir}/component-config.json`
* @property {Array.<String>} [mixinDirs] List of directories where to look
* for files containing model mixin definitions. All files (mixins) found
* in these directory are loaded.
* @property {Array.<String>} [mixinSources] List of directories where to look
* for files containing model mixin definitions. Only mixins used by
* application models are loaded from these directories.
* @property {Array.<String>} [bootDirs] List of directories where to look
* for boot scripts.
* @property {Array.<String>} [bootScripts] List of script files to execute
* on boot.
* @property {String|Function|Boolean} [normalization] Mixin normalization
* format: false, 'none', 'classify', 'dasherize' - defaults to 'classify'.
* @end
* @param {Function} [callback] Callback function.
*
* @header boot(app, [options], [callback])
*/
exports = module.exports = function bootLoopBackApp(app, options, callback) {
if (typeof options === 'string') {
// The 2nd arg is appRootDir
options = {appRootDir: options};
}
if (typeof options === 'function' && callback === undefined) {
callback = options;
options = {};
}
options = options || {};
// backwards compatibility with loopback's app.boot
options.env = options.env || app.get('env');
const bootstrapper = new Bootstrapper(options);
const context = {
bootstrapper: bootstrapper,
app: app,
};
return bootstrapper.run(context, callback);
};
exports.compile = function(options, done) {
const bootstrapper = new Bootstrapper(options);
bootstrapper.phases = ['load', 'compile'];
const context = {};
return bootstrapper.run(context, done);
};
/**
* Compile boot instructions and add them to a browserify bundler.
* @param {Object|String} options as described in `bootLoopBackApp` above.
* @property {String} [appId] Application identifier used to load the correct
* boot configuration when building multiple applications using browserify.
* @end
* @param {Object} bundler A browserify bundler created by `browserify()`.
*
* @header boot.compileToBrowserify(options, bundler)
*/
exports.compileToBrowserify = function(options, bundler, done) {
return exports.compile(options, function(err, context) {
if (err) return done(err);
addInstructionsToBrowserify({instructions: context.instructions},
bundler);
done();
});
};
exports.addInstructionsToBrowserify = addInstructionsToBrowserify;
exports.Bootstrapper = Bootstrapper;
exports.PluginBase = PluginBase;
exports.execute = function(app, instructions, done) {
const bootstrapper = new Bootstrapper(
{phases: ['starting', 'start', 'started']},
);
const context = {
app: app,
instructions: instructions,
};
return bootstrapper.run(context, done);
};