loopback-boot/lib/plugins/application.js

138 lines
3.6 KiB
JavaScript

// Copyright IBM Corp. 2014,2016. 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';
var util = require('util');
var assert = require('assert');
var semver = require('semver');
var PluginBase = require('../plugin-base');
var g = require('../globalize');
module.exports = function(options) {
return new Application(options);
};
function Application(options) {
PluginBase.call(this, options, 'application', 'config');
}
util.inherits(Application, PluginBase);
function assertLoopBackVersion(app) {
var RANGE = '2.x || 3.x';
var loopback = app.loopback;
// remove any pre-release tag from the version string,
// because semver has special treatment of pre-release versions,
// while loopback-boot treats pre-releases the same way as regular versions
var version = (loopback.version || '1.0.0').replace(/-.*$/, '');
if (!semver.satisfies(version, RANGE)) {
var msg = g.f(
'The `app` is powered by an incompatible loopback version %s. ' +
'Supported versions: %s',
loopback.version || '(unknown)',
RANGE
);
throw new Error(msg);
}
}
function setEnv(app, env) {
if (env !== undefined)
app.set('env', env);
}
function setHost(app, appConfig) {
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var host =
process.env.npm_config_host ||
process.env.OPENSHIFT_SLS_IP ||
process.env.OPENSHIFT_NODEJS_IP ||
process.env.HOST ||
process.env.VCAP_APP_HOST ||
appConfig.host ||
process.env.npm_package_config_host ||
app.get('host');
if (host !== undefined) {
assert(typeof host === 'string', 'app.host must be a string');
app.set('host', host);
}
}
function setPort(app, appConfig) {
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var port = find([
process.env.npm_config_port,
process.env.OPENSHIFT_SLS_PORT,
process.env.OPENSHIFT_NODEJS_PORT,
process.env.PORT,
process.env.VCAP_APP_PORT,
appConfig.port,
process.env.npm_package_config_port,
app.get('port'),
3000,
], function(p) {
return p != null;
});
if (port !== undefined) {
var portType = typeof port;
assert(portType === 'string' || portType === 'number',
'app.port must be a string or number');
app.set('port', port);
}
}
function find(array, predicate) {
return array.filter(predicate)[0];
}
function setApiRoot(app, appConfig) {
var restApiRoot =
appConfig.restApiRoot ||
app.get('restApiRoot') ||
'/api';
assert(restApiRoot !== undefined, 'app.restBasePath is required');
assert(typeof restApiRoot === 'string',
'app.restApiRoot must be a string');
assert(/^\//.test(restApiRoot),
'app.restApiRoot must start with "/"');
app.set('restApiRoot', restApiRoot);
}
function applyAppConfig(app, appConfig) {
for (var configKey in appConfig) {
var cur = app.get(configKey);
if (cur === undefined || cur === null) {
app.set(configKey, appConfig[configKey]);
}
}
}
Application.prototype.starting = function(context) {
var app = context.app;
app.booting = true;
assertLoopBackVersion(app);
var appConfig = context.instructions.application;
setEnv(app, context.instructions.env || this.options.env);
setHost(app, appConfig);
setPort(app, appConfig);
setApiRoot(app, appConfig);
applyAppConfig(app, appConfig);
};
Application.prototype.started = function(context, done) {
var app = context.app;
app.booting = false;
process.nextTick(function() {
app.emit('booted');
done();
});
};