merge from sl-origin master
This commit is contained in:
commit
b3d1a2f4a7
|
@ -1,3 +1,2 @@
|
|||
node_modules/
|
||||
coverage/
|
||||
test/sandbox/
|
25
.jscsrc
25
.jscsrc
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"preset": "google",
|
||||
"requireCurlyBraces": [
|
||||
"do",
|
||||
"try",
|
||||
"catch"
|
||||
],
|
||||
"disallowMultipleVarDecl": "exceptUndefined",
|
||||
"disallowSpacesInsideObjectBrackets": null,
|
||||
"requireSpaceAfterLineComment": true,
|
||||
"maximumLineLength": {
|
||||
"value": 80,
|
||||
"allowRegex": true
|
||||
},
|
||||
"validateJSDoc": {
|
||||
"checkParamNames": false,
|
||||
"checkRedundantParams": false,
|
||||
"requireParamTypes": true
|
||||
},
|
||||
"excludeFiles": [
|
||||
"node_modules/**",
|
||||
"coverage/**",
|
||||
"test/sandbox/**"
|
||||
]
|
||||
}
|
21
.jshintrc
21
.jshintrc
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"eqnull" : true,
|
||||
"indent": 2,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"quotmark": "single",
|
||||
"newcap": true,
|
||||
"nonew": true,
|
||||
"sub": true,
|
||||
"unused": "vars",
|
||||
"globals": {
|
||||
"describe": false,
|
||||
"it": false,
|
||||
"before": false,
|
||||
"beforeEach": false,
|
||||
"after": false,
|
||||
"afterEach": false
|
||||
}
|
||||
}
|
36
CHANGES.md
36
CHANGES.md
|
@ -1,3 +1,35 @@
|
|||
2016-06-20, Version 2.19.0
|
||||
==========================
|
||||
|
||||
* update copyright notices and license (Ryan Graham)
|
||||
|
||||
* Add flag var lazyConnect to ds config (juehou)
|
||||
|
||||
|
||||
2016-04-13, Version 2.18.1
|
||||
==========================
|
||||
|
||||
* parse config: should ignore null values (Loïc Mahieu)
|
||||
|
||||
|
||||
2016-04-07, Version 2.18.0
|
||||
==========================
|
||||
|
||||
* Dynamic datasources.json from ENV and config.json (David Cheung)
|
||||
|
||||
* Use eslint with loopback config (Miroslav Bajtoš)
|
||||
|
||||
|
||||
2016-02-23, Version 2.17.0
|
||||
==========================
|
||||
|
||||
* executor: move "booted" and cb() to the next tick (Miroslav Bajtoš)
|
||||
|
||||
* Fix lodash 4.0.0 breaking changes (Jérémie Drouet)
|
||||
|
||||
* When config is overriden with null don't merge (Farid Neshat)
|
||||
|
||||
|
||||
2015-12-22, Version 2.16.0
|
||||
==========================
|
||||
|
||||
|
@ -314,8 +346,6 @@
|
|||
2014-07-17, Version v2.0.0-beta3
|
||||
================================
|
||||
|
||||
* v2.0.0-beta3 (Miroslav Bajtoš)
|
||||
|
||||
* compiler: return a clone of instructions (Miroslav Bajtoš)
|
||||
|
||||
|
||||
|
@ -334,8 +364,6 @@
|
|||
2014-06-26, Version 2.0.0-beta1
|
||||
===============================
|
||||
|
||||
* 2.0.0-beta1 (Miroslav Bajtoš)
|
||||
|
||||
* test: fix jshint warnings (Miroslav Bajtoš)
|
||||
|
||||
* compiler: fix references to loopback (Miroslav Bajtoš)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) IBM Corp. 2014,2016. All Rights Reserved.
|
||||
Node module: loopback-boot
|
||||
This project is licensed under the MIT License, full text below.
|
||||
|
||||
--------
|
||||
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -1,9 +0,0 @@
|
|||
Copyright (c) 2013-2015 StrongLoop, Inc and other contributors.
|
||||
|
||||
loopback-boot uses a dual license model.
|
||||
|
||||
You may use this library under the terms of the [MIT License][],
|
||||
or under the terms of the [StrongLoop Subscription Agreement][].
|
||||
|
||||
[MIT License]: http://opensource.org/licenses/MIT
|
||||
[StrongLoop Subscription Agreement]: http://strongloop.com/license
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var execute = require('./lib/executor');
|
||||
|
||||
/**
|
||||
|
|
7
index.js
7
index.js
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var ConfigLoader = require('./lib/config-loader');
|
||||
var compile = require('./lib/compiler');
|
||||
var execute = require('./lib/executor');
|
||||
|
@ -154,7 +159,7 @@ exports.compileToBrowserify = function(options, bundler) {
|
|||
addInstructionsToBrowserify(compile(options), bundler);
|
||||
};
|
||||
|
||||
/*-- undocumented low-level API --*/
|
||||
/* -- undocumented low-level API -- */
|
||||
|
||||
exports.ConfigLoader = ConfigLoader;
|
||||
exports.compile = compile;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var commondir = require('commondir');
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var assert = require('assert');
|
||||
var cloneDeep = require('lodash').cloneDeep;
|
||||
var fs = require('fs');
|
||||
|
@ -102,8 +107,8 @@ module.exports = function compile(options) {
|
|||
components: componentInstructions,
|
||||
mixins: mixinInstructions,
|
||||
files: {
|
||||
boot: bootScripts
|
||||
}
|
||||
boot: bootScripts,
|
||||
},
|
||||
};
|
||||
|
||||
if (options.appId)
|
||||
|
@ -214,7 +219,7 @@ function buildAllModelInstructions(rootDir, modelsConfig, sources,
|
|||
name: name,
|
||||
config: config,
|
||||
definition: definition.definition,
|
||||
sourceFile: definition.sourceFile
|
||||
sourceFile: definition.sourceFile,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -414,7 +419,6 @@ function tryResolveAppPath(rootDir, relativePath, resolveOptions) {
|
|||
try {
|
||||
// NOTE(bajtos) We need to create a proper String object here,
|
||||
// otherwise we can't attach additional properties to it
|
||||
/*jshint -W053 */
|
||||
var filePath = new String(require.resolve(absPath));
|
||||
filePath.unresolvedPath = absPath;
|
||||
return filePath;
|
||||
|
@ -456,7 +460,7 @@ function loadModelDefinition(rootDir, jsonFile, allFiles) {
|
|||
|
||||
return {
|
||||
definition: definition,
|
||||
sourceFile: sourceFile
|
||||
sourceFile: sourceFile,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -494,7 +498,7 @@ function buildMiddlewareInstructions(rootDir, config) {
|
|||
|
||||
var item = {
|
||||
sourceFile: resolved.sourceFile,
|
||||
config: middlewareConfig
|
||||
config: middlewareConfig,
|
||||
};
|
||||
if (resolved.fragment) {
|
||||
item.fragment = resolved.fragment;
|
||||
|
@ -516,13 +520,13 @@ function buildMiddlewareInstructions(rootDir, config) {
|
|||
|
||||
return {
|
||||
phases: flattenedPhaseNames,
|
||||
middleware: middlewareList
|
||||
middleware: middlewareList,
|
||||
};
|
||||
}
|
||||
|
||||
function resolveMiddlewarePath(rootDir, middleware, config) {
|
||||
var resolved = {
|
||||
optional: !!config.optional
|
||||
optional: !!config.optional,
|
||||
};
|
||||
|
||||
var segments = middleware.split('#');
|
||||
|
@ -531,7 +535,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
|
|||
var middlewarePath = pathName;
|
||||
var opts = {
|
||||
strict: true,
|
||||
optional: !!config.optional
|
||||
optional: !!config.optional,
|
||||
};
|
||||
|
||||
if (fragment) {
|
||||
|
@ -551,7 +555,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
|
|||
// node_modules/strong-express-metrics
|
||||
// instead of
|
||||
// node_modules/strong-express-metrics/index.js
|
||||
fullResolve: false
|
||||
fullResolve: false,
|
||||
});
|
||||
var sourceFile = resolveAppScriptPath(rootDir, middlewarePath, resolveOpts);
|
||||
|
||||
|
@ -580,14 +584,13 @@ function resolveMiddlewarePath(rootDir, middleware, config) {
|
|||
// pathName + '/' + fragment
|
||||
];
|
||||
|
||||
var err;
|
||||
var err = undefined; // see https://github.com/eslint/eslint/issues/5744
|
||||
for (var ix in candidates) {
|
||||
try {
|
||||
resolved.sourceFile = resolveAppScriptPath(rootDir, candidates[ix], opts);
|
||||
delete resolved.fragment;
|
||||
return resolved;
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
// Report the error for the first candidate when no candidate matches
|
||||
if (!err) err = e;
|
||||
}
|
||||
|
@ -614,7 +617,7 @@ function buildComponentInstructions(rootDir, componentConfig) {
|
|||
.map(function(name) {
|
||||
return {
|
||||
sourceFile: resolveAppScriptPath(rootDir, name, { strict: true }),
|
||||
config: componentConfig[name]
|
||||
config: componentConfig[name],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -634,11 +637,11 @@ function resolveRelativePaths(relativePaths, appRootDir) {
|
|||
function getExcludedExtensions() {
|
||||
return {
|
||||
'.json': '.json',
|
||||
'.node': 'node'
|
||||
'.node': 'node',
|
||||
};
|
||||
}
|
||||
|
||||
function isPreferredExtension (filename) {
|
||||
function isPreferredExtension(filename) {
|
||||
var includeExtensions = require.extensions;
|
||||
|
||||
var ext = path.extname(filename);
|
||||
|
@ -792,7 +795,9 @@ function normalizeMixinName(str, options) {
|
|||
case 'classify':
|
||||
str = String(str).replace(/([A-Z]+)/g, ' $1').trim();
|
||||
str = String(str).replace(/[\W_]/g, ' ').toLowerCase();
|
||||
str = str.replace(/(?:^|\s|-)\S/g, function(c) { return c.toUpperCase(); });
|
||||
str = str.replace(/(?:^|\s|-)\S/g, function(c) {
|
||||
return c.toUpperCase();
|
||||
});
|
||||
str = str.replace(/\s+/g, '');
|
||||
return str;
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var debug = require('debug')('loopback:boot:config-loader');
|
||||
|
@ -32,7 +37,6 @@ ConfigLoader.loadDataSources = function(rootDir, env) {
|
|||
* @returns {Object}
|
||||
*/
|
||||
ConfigLoader.loadModels = function(rootDir, env) {
|
||||
/*jshint unused:false */
|
||||
return loadNamed(rootDir, env, 'model-config', mergeModelConfig);
|
||||
};
|
||||
|
||||
|
@ -98,7 +102,7 @@ function findConfigFiles(appRootDir, env, name) {
|
|||
var candidates = [
|
||||
master,
|
||||
ifExistsWithAnyExt(name + '.local'),
|
||||
ifExistsWithAnyExt(name + '.' + env)
|
||||
ifExistsWithAnyExt(name + '.' + env),
|
||||
];
|
||||
|
||||
return candidates.filter(function(c) { return c !== undefined; });
|
||||
|
@ -124,7 +128,7 @@ function loadConfigFiles(files) {
|
|||
var config = require(f);
|
||||
Object.defineProperty(config, '_filename', {
|
||||
enumerable: false,
|
||||
value: f
|
||||
value: f,
|
||||
});
|
||||
return config;
|
||||
});
|
||||
|
@ -166,7 +170,7 @@ function mergeAppConfig(target, config, fileName) {
|
|||
}
|
||||
|
||||
function mergeMiddlewareConfig(target, config, fileName) {
|
||||
var err;
|
||||
var err = undefined; // see https://github.com/eslint/eslint/issues/5744
|
||||
for (var phase in config) {
|
||||
if (phase in target) {
|
||||
err = mergePhaseConfig(target[phase], config[phase], phase);
|
||||
|
@ -203,7 +207,7 @@ function mergeNamedItems(arr1, arr2, key) {
|
|||
}
|
||||
|
||||
function mergePhaseConfig(target, config, phase) {
|
||||
var err;
|
||||
var err = undefined; // see https://github.com/eslint/eslint/issues/5744
|
||||
for (var mw in config) {
|
||||
if (mw in target) {
|
||||
var targetMiddleware = target[mw];
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var assert = require('assert');
|
||||
var semver = require('semver');
|
||||
var debug = require('debug')('loopback:boot:executor');
|
||||
|
@ -43,15 +48,20 @@ module.exports = function execute(app, instructions, callback) {
|
|||
function(done) {
|
||||
enableAnonymousSwagger(app, instructions);
|
||||
done();
|
||||
}], function(err) {
|
||||
app.booting = false;
|
||||
},
|
||||
// Ensure both the "booted" event and the callback are always called
|
||||
// in the next tick of the even loop.
|
||||
// See http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
|
||||
process.nextTick,
|
||||
], function(err) {
|
||||
app.booting = false;
|
||||
|
||||
if (err) return callback(err);
|
||||
if (err) return callback(err);
|
||||
|
||||
app.emit('booted');
|
||||
app.emit('booted');
|
||||
|
||||
callback();
|
||||
});
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
function patchAppLoopback(app) {
|
||||
|
@ -123,7 +133,7 @@ function setPort(app, instructions) {
|
|||
instructions.config.port,
|
||||
process.env.npm_package_config_port,
|
||||
app.get('port'),
|
||||
3000
|
||||
3000,
|
||||
], function(p) {
|
||||
return p != null;
|
||||
});
|
||||
|
@ -166,6 +176,15 @@ function applyAppConfig(app, instructions) {
|
|||
|
||||
function setupDataSources(app, instructions) {
|
||||
forEachKeyedObject(instructions.dataSources, function(key, obj) {
|
||||
var opts = {
|
||||
useEnvVars: true,
|
||||
};
|
||||
obj = getUpdatedConfigObject(app, obj, opts);
|
||||
var lazyConnect = process.env.LB_LAZYCONNECT_DATASOURCES;
|
||||
if (lazyConnect) {
|
||||
obj.lazyConnect =
|
||||
lazyConnect === 'false' || lazyConnect === '0' ? false : true;
|
||||
}
|
||||
app.dataSource(key, obj);
|
||||
});
|
||||
}
|
||||
|
@ -272,7 +291,7 @@ function runScripts(app, list, callback) {
|
|||
debug('Exported function detected %s', filepath);
|
||||
functions.push({
|
||||
path: filepath,
|
||||
func: exports
|
||||
func: exports,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -325,24 +344,42 @@ function setupMiddleware(app, instructions) {
|
|||
}
|
||||
assert(typeof factory === 'function',
|
||||
'Middleware factory must be a function');
|
||||
data.config = getUpdatedConfigObject(app, data.config);
|
||||
var opts = {
|
||||
useEnvVars: true,
|
||||
};
|
||||
data.config = getUpdatedConfigObject(app, data.config, opts);
|
||||
app.middlewareFromConfig(factory, data.config);
|
||||
});
|
||||
}
|
||||
|
||||
function getUpdatedConfigObject(app, config) {
|
||||
function getUpdatedConfigObject(app, config, opts) {
|
||||
var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/;
|
||||
var useEnvVars = opts && opts.useEnvVars;
|
||||
|
||||
function getConfigVariable(param) {
|
||||
var configVariable = param;
|
||||
var match = configVariable.match(DYNAMIC_CONFIG_PARAM);
|
||||
if (match) {
|
||||
var appValue = app.get(match[1]);
|
||||
if (appValue !== undefined) {
|
||||
var varName = match[1];
|
||||
if (useEnvVars && process.env[varName] !== undefined) {
|
||||
debug('Dynamic Configuration: Resolved via process.env: %s as %s',
|
||||
process.env[varName], param);
|
||||
configVariable = process.env[varName];
|
||||
} else if (app.get(varName) !== undefined) {
|
||||
debug('Dynamic Configuration: Resolved via app.get(): %s as %s',
|
||||
app.get(varName), param);
|
||||
var appValue = app.get(varName);
|
||||
configVariable = appValue;
|
||||
} else {
|
||||
console.warn('%s does not resolve to a valid value. ' +
|
||||
'"%s" must be resolvable by app.get().', param, match[1]);
|
||||
// previously it returns the original string such as "${restApiRoot}"
|
||||
// it will now return `undefined`, for the use case of
|
||||
// dynamic datasources url:`undefined` to fallback to other parameters
|
||||
configVariable = undefined;
|
||||
console.warn('%s does not resolve to a valid value, returned as %s. ' +
|
||||
'"%s" must be resolvable in Environment variable or by app.get().',
|
||||
param, configVariable, varName);
|
||||
debug('Dynamic Configuration: Cannot resolve variable for `%s`, ' +
|
||||
'returned as %s', varName, configVariable);
|
||||
}
|
||||
}
|
||||
return configVariable;
|
||||
|
@ -373,6 +410,8 @@ function getUpdatedConfigObject(app, config) {
|
|||
interpolated[configKey] = value.map(interpolateVariables);
|
||||
} else if (typeof value === 'string') {
|
||||
interpolated[configKey] = getConfigVariable(value);
|
||||
} else if (value === null) {
|
||||
interpolated[configKey] = value;
|
||||
} else if (typeof value === 'object' && Object.keys(value).length) {
|
||||
interpolated[configKey] = interpolateVariables(value);
|
||||
} else {
|
||||
|
@ -389,7 +428,10 @@ function setupComponents(app, instructions) {
|
|||
instructions.components.forEach(function(data) {
|
||||
debug('Configuring component %j', data.sourceFile);
|
||||
var configFn = require(data.sourceFile);
|
||||
data.config = getUpdatedConfigObject(app, data.config);
|
||||
var opts = {
|
||||
useEnvVars: true,
|
||||
};
|
||||
data.config = getUpdatedConfigObject(app, data.config, opts);
|
||||
configFn(app, data.config);
|
||||
});
|
||||
}
|
||||
|
|
11
package.json
11
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "loopback-boot",
|
||||
"version": "2.16.0",
|
||||
"version": "2.19.0",
|
||||
"description": "Convention-based bootstrapper for LoopBack applications",
|
||||
"keywords": [
|
||||
"StrongLoop",
|
||||
|
@ -15,8 +15,9 @@
|
|||
"main": "index.js",
|
||||
"browser": "browser.js",
|
||||
"scripts": {
|
||||
"pretest": "jscs . && jshint .",
|
||||
"test": "mocha"
|
||||
"test": "mocha",
|
||||
"posttest": "npm run lint",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -32,9 +33,9 @@
|
|||
"chai": "^1.10.0",
|
||||
"coffee-script": "^1.8.0",
|
||||
"coffeeify": "^0.7.0",
|
||||
"eslint": "^2.5.3",
|
||||
"eslint-config-loopback": "^1.0.0",
|
||||
"fs-extra": "^0.12.0",
|
||||
"jscs": "^1.7.3",
|
||||
"jshint": "^2.5.6",
|
||||
"loopback": "^2.16.3",
|
||||
"mocha": "^1.19.0",
|
||||
"supertest": "^0.14.0"
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015,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
|
||||
|
||||
var boot = require('../');
|
||||
var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox;
|
||||
var fs = require('fs');
|
||||
|
@ -22,14 +27,14 @@ describe('browser support for multiple apps', function() {
|
|||
{
|
||||
appDir: app1Dir,
|
||||
appFile: './app.js',
|
||||
moduleName: 'browser-app'
|
||||
moduleName: 'browser-app',
|
||||
},
|
||||
{
|
||||
appDir: app2Dir,
|
||||
appFile: './app.js',
|
||||
moduleName: 'browser-app2',
|
||||
appId: 'browserApp2'
|
||||
}
|
||||
appId: 'browserApp2',
|
||||
},
|
||||
];
|
||||
|
||||
browserifyTestApps(apps, function(err, bundlePath) {
|
||||
|
@ -55,7 +60,7 @@ describe('browser support for multiple apps', function() {
|
|||
|
||||
function browserifyTestApps(apps, next) {
|
||||
var b = browserify({
|
||||
debug: true
|
||||
debug: true,
|
||||
});
|
||||
|
||||
for (var i in apps) {
|
||||
|
@ -65,13 +70,13 @@ function browserifyTestApps(apps, next) {
|
|||
var appId = apps[i].appId;
|
||||
|
||||
appFile = path.join(appDir, appFile);
|
||||
b.require(appFile, {expose: moduleName});
|
||||
b.require(appFile, { expose: moduleName });
|
||||
|
||||
var opts = appDir;
|
||||
if (appId) {
|
||||
opts = {
|
||||
appId: appId,
|
||||
appRootDir: appDir
|
||||
appRootDir: appDir,
|
||||
};
|
||||
}
|
||||
boot.compileToBrowserify(opts, b);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var boot = require('../');
|
||||
var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox;
|
||||
var fs = require('fs');
|
||||
|
@ -13,7 +18,7 @@ var compileStrategies = {
|
|||
'default': function(appDir) {
|
||||
var b = browserify({
|
||||
basedir: appDir,
|
||||
debug: true
|
||||
debug: true,
|
||||
});
|
||||
|
||||
b.require('./app.js', { expose: 'browser-app' });
|
||||
|
@ -24,7 +29,7 @@ var compileStrategies = {
|
|||
var b = browserify({
|
||||
basedir: appDir,
|
||||
extensions: ['.coffee'],
|
||||
debug: true
|
||||
debug: true,
|
||||
});
|
||||
|
||||
b.transform('coffeeify');
|
||||
|
@ -64,7 +69,7 @@ describe('browser support', function() {
|
|||
it('loads mixins', function(done) {
|
||||
var appDir = path.resolve(__dirname, './fixtures/browser-app');
|
||||
var options = {
|
||||
appRootDir: appDir
|
||||
appRootDir: appDir,
|
||||
};
|
||||
|
||||
browserifyTestApp(options, function(err, bundlePath) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var async = require('async');
|
||||
var boot = require('../');
|
||||
var path = require('path');
|
||||
|
@ -37,22 +42,22 @@ describe('executor', function() {
|
|||
host: '127.0.0.1',
|
||||
restApiRoot: '/rest-api',
|
||||
foo: { bar: 'bat' },
|
||||
baz: true
|
||||
baz: true,
|
||||
},
|
||||
models: [
|
||||
{
|
||||
name: 'User',
|
||||
config: {
|
||||
dataSource: 'the-db'
|
||||
}
|
||||
}
|
||||
dataSource: 'the-db',
|
||||
},
|
||||
},
|
||||
],
|
||||
dataSources: {
|
||||
'the-db': {
|
||||
connector: 'memory',
|
||||
defaultForType: 'db'
|
||||
}
|
||||
}
|
||||
defaultForType: 'db',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
describe('when booting', function() {
|
||||
|
@ -66,15 +71,15 @@ describe('executor', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('should emit the `booted` event', function(done) {
|
||||
it('should emit the `booted` event in the next tick', function(done) {
|
||||
boot.execute(app, dummyInstructions, function(err) {
|
||||
expect(err).to.be.undefined();
|
||||
});
|
||||
app.on('booted', function() {
|
||||
// This test fails with a timeout when the `booted` event has not been
|
||||
// emitted correctly
|
||||
done();
|
||||
});
|
||||
boot.execute(app, dummyInstructions, function(err) {
|
||||
expect(err).to.be.undefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should work when called synchronously', function() {
|
||||
|
@ -109,9 +114,9 @@ describe('executor', function() {
|
|||
name: 'Customer',
|
||||
base: 'User',
|
||||
},
|
||||
sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js')
|
||||
}
|
||||
]
|
||||
sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js'),
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
expect(app.models.Customer).to.exist();
|
||||
|
@ -127,9 +132,9 @@ describe('executor', function() {
|
|||
name: 'Vehicle',
|
||||
config: undefined,
|
||||
definition: {
|
||||
name: 'Vehicle'
|
||||
name: 'Vehicle',
|
||||
},
|
||||
sourceFile: undefined
|
||||
sourceFile: undefined,
|
||||
},
|
||||
{
|
||||
name: 'Car',
|
||||
|
@ -138,9 +143,9 @@ describe('executor', function() {
|
|||
name: 'Car',
|
||||
base: 'Vehicle',
|
||||
},
|
||||
sourceFile: undefined
|
||||
sourceFile: undefined,
|
||||
},
|
||||
]
|
||||
],
|
||||
}));
|
||||
|
||||
expect(Object.keys(app.models)).to.eql(['Car']);
|
||||
|
@ -166,15 +171,15 @@ describe('executor', function() {
|
|||
name: 'Customer',
|
||||
config: { dataSource: 'db' },
|
||||
definition: { name: 'Customer' },
|
||||
sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js')
|
||||
sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js'),
|
||||
},
|
||||
{
|
||||
name: 'UniqueName',
|
||||
config: { dataSource: 'db' },
|
||||
definition: { name: 'UniqueName' },
|
||||
sourceFile: undefined
|
||||
}
|
||||
]
|
||||
sourceFile: undefined,
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
expect(app.models.Customer._modelsWhenAttached).to.include('UniqueName');
|
||||
|
@ -188,9 +193,9 @@ describe('executor', function() {
|
|||
name: 'LocalCustomer',
|
||||
config: { dataSource: 'db' },
|
||||
definition: { name: 'LocalCustomer' },
|
||||
sourceFile: undefined
|
||||
}
|
||||
]
|
||||
sourceFile: undefined,
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
expect(Object.keys(loopback.registry.modelBuilder.models), 'global models')
|
||||
|
@ -204,7 +209,7 @@ describe('executor', function() {
|
|||
'require("doesnt-exist"); module.exports = {};');
|
||||
|
||||
function doBoot() {
|
||||
boot.execute(app, someInstructions({ files: { boot: [file] } }));
|
||||
boot.execute(app, someInstructions({ files: { boot: [file] }}));
|
||||
}
|
||||
|
||||
expect(doBoot).to.throw(/Cannot find module \'doesnt-exist\'/);
|
||||
|
@ -236,7 +241,7 @@ describe('executor', function() {
|
|||
require.resolve('loopback/common/models/user.json')
|
||||
),
|
||||
config: { dataSource: 'db' },
|
||||
sourceFile: require.resolve('loopback/common/models/user.js')
|
||||
sourceFile: require.resolve('loopback/common/models/user.js'),
|
||||
};
|
||||
builtinModel.definition.redefined = true;
|
||||
|
||||
|
@ -260,7 +265,7 @@ describe('executor', function() {
|
|||
'barLoaded',
|
||||
'barSyncLoaded',
|
||||
'fooLoaded',
|
||||
'barStarted'
|
||||
'barStarted',
|
||||
]);
|
||||
|
||||
// bar finished happens in the next tick
|
||||
|
@ -272,7 +277,7 @@ describe('executor', function() {
|
|||
'fooLoaded',
|
||||
'barStarted',
|
||||
'barFinished',
|
||||
'barSyncExecuted'
|
||||
'barSyncExecuted',
|
||||
]);
|
||||
done();
|
||||
}, 10);
|
||||
|
@ -288,7 +293,7 @@ describe('executor', function() {
|
|||
'fooLoaded',
|
||||
'barStarted',
|
||||
'barFinished',
|
||||
'barSyncExecuted'
|
||||
'barSyncExecuted',
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
@ -306,11 +311,11 @@ describe('executor', function() {
|
|||
'function(Model, options) {}');
|
||||
|
||||
appdir.writeConfigFileSync('custom-mixins/time-stamps.json', {
|
||||
name: 'Timestamping'
|
||||
name: 'Timestamping',
|
||||
});
|
||||
|
||||
options = {
|
||||
appRootDir: appdir.PATH
|
||||
appRootDir: appdir.PATH,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -357,8 +362,8 @@ describe('executor', function() {
|
|||
boot.execute(app, someInstructions({
|
||||
config: {
|
||||
port: undefined,
|
||||
host: undefined
|
||||
}
|
||||
host: undefined,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -388,6 +393,7 @@ describe('executor', function() {
|
|||
|
||||
it('should prioritize host sources', function() {
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
/*eslint-disable camelcase*/
|
||||
process.env.npm_config_host = randomHost();
|
||||
process.env.OPENSHIFT_SLS_IP = randomHost();
|
||||
process.env.OPENSHIFT_NODEJS_IP = randomHost();
|
||||
|
@ -397,9 +403,11 @@ describe('executor', function() {
|
|||
|
||||
bootWithDefaults();
|
||||
assert.equal(app.get('host'), process.env.npm_config_host);
|
||||
/*eslint-enable camelcase*/
|
||||
});
|
||||
|
||||
it('should prioritize port sources', function() {
|
||||
/*eslint-disable camelcase*/
|
||||
process.env.npm_config_port = randomPort();
|
||||
process.env.OPENSHIFT_SLS_PORT = randomPort();
|
||||
process.env.OPENSHIFT_NODEJS_PORT = randomPort();
|
||||
|
@ -409,6 +417,7 @@ describe('executor', function() {
|
|||
|
||||
bootWithDefaults();
|
||||
assert.equal(app.get('port'), process.env.npm_config_port);
|
||||
/*eslint-enable camelcase*/
|
||||
});
|
||||
|
||||
function randomHost() {
|
||||
|
@ -420,24 +429,28 @@ describe('executor', function() {
|
|||
}
|
||||
|
||||
it('should honor 0 for free port', function() {
|
||||
boot.execute(app, someInstructions({ config: { port: 0 } }));
|
||||
boot.execute(app, someInstructions({ config: { port: 0 }}));
|
||||
assert.equal(app.get('port'), 0);
|
||||
});
|
||||
|
||||
it('should default to port 3000', function() {
|
||||
boot.execute(app, someInstructions({ config: { port: undefined } }));
|
||||
boot.execute(app, someInstructions({ config: { port: undefined }}));
|
||||
assert.equal(app.get('port'), 3000);
|
||||
});
|
||||
|
||||
it('should respect named pipes port values in ENV', function() {
|
||||
var NAMED_PORT = '\\.\\pipe\\test';
|
||||
process.env.PORT = NAMED_PORT;
|
||||
boot.execute(app, someInstructions({ config: { port: 3000 } }));
|
||||
boot.execute(app, someInstructions({ config: { port: 3000 }}));
|
||||
assert.equal(app.get('port'), NAMED_PORT);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with middleware.json', function() {
|
||||
beforeEach(function() {
|
||||
delete process.env.restApiRoot;
|
||||
});
|
||||
|
||||
it('should parse a simple config variable', function(done) {
|
||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||
{ path: '${restApiRoot}' }
|
||||
|
@ -450,6 +463,36 @@ describe('executor', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('should parse simple config variable from env var', function(done) {
|
||||
process.env.restApiRoot = '/url-from-env-var';
|
||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||
{ path: '${restApiRoot}' }
|
||||
));
|
||||
|
||||
supertest(app).get('/url-from-env-var').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.path).to.equal('/url-from-env-var');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('dynamic variable from `env var` should have' +
|
||||
' precedence over app.get()', function(done) {
|
||||
process.env.restApiRoot = '/url-from-env-var';
|
||||
var bootInstructions;
|
||||
bootInstructions = simpleMiddlewareConfig('routes',
|
||||
{ path: '${restApiRoot}' });
|
||||
bootInstructions.config = { restApiRoot: '/url-from-config' };
|
||||
boot.execute(app, someInstructions(bootInstructions));
|
||||
|
||||
supertest(app).get('/url-from-env-var').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(app.get('restApiRoot')).to.equal('/url-from-config');
|
||||
expect(res.body.path).to.equal('/url-from-env-var');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse multiple config variables', function(done) {
|
||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||
{ path: '${restApiRoot}', env: '${env}' }
|
||||
|
@ -479,13 +522,13 @@ describe('executor', function() {
|
|||
|
||||
it('should parse config variables in an object', function(done) {
|
||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||
{ info: { path: '${restApiRoot}' } }
|
||||
{ info: { path: '${restApiRoot}' }}
|
||||
));
|
||||
|
||||
supertest(app).get('/').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.info).to.eql({
|
||||
path: app.get('restApiRoot')
|
||||
path: app.get('restApiRoot'),
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
@ -493,13 +536,30 @@ describe('executor', function() {
|
|||
|
||||
it('should parse config variables in a nested object', function(done) {
|
||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||
{ nested: { info: { path: '${restApiRoot}' } } }
|
||||
{ nested: { info: { path: '${restApiRoot}' }}}
|
||||
));
|
||||
|
||||
supertest(app).get('/').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.nested).to.eql({
|
||||
info: { path: app.get('restApiRoot') }
|
||||
info: { path: app.get('restApiRoot') },
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse config variables with null values', function(done) {
|
||||
boot.execute(app, simpleMiddlewareConfig('routes',
|
||||
{ nested: { info: { path: '${restApiRoot}', some: null }}}
|
||||
));
|
||||
|
||||
supertest(app).get('/').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.nested).to.eql({
|
||||
info: {
|
||||
path: app.get('restApiRoot'),
|
||||
some: null,
|
||||
},
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
@ -509,7 +569,7 @@ describe('executor', function() {
|
|||
var invalidDataTypes = [undefined, function() {}];
|
||||
async.each(invalidDataTypes, function(invalidDataType, cb) {
|
||||
var config = simpleMiddlewareConfig('routes', {
|
||||
path: invalidDataType
|
||||
path: invalidDataType,
|
||||
});
|
||||
boot.execute(app, config);
|
||||
|
||||
|
@ -525,7 +585,7 @@ describe('executor', function() {
|
|||
|
||||
it('should parse valid config variables', function(done) {
|
||||
var config = simpleMiddlewareConfig('routes', {
|
||||
props: ['a', '${vVar}', 1, true, function() {}, {x:1, y: '${y}'}]
|
||||
props: ['a', '${vVar}', 1, true, function() {}, { x: 1, y: '${y}' }],
|
||||
});
|
||||
boot.execute(app, config);
|
||||
|
||||
|
@ -552,6 +612,10 @@ describe('executor', function() {
|
|||
});
|
||||
|
||||
describe('with component-config.json', function() {
|
||||
beforeEach(function() {
|
||||
delete process.env.DYNAMIC_ENVVAR;
|
||||
delete process.env.DYNAMIC_VARIABLE;
|
||||
});
|
||||
|
||||
it('should parse a simple config variable', function(done) {
|
||||
boot.execute(app, simpleComponentConfig(
|
||||
|
@ -565,6 +629,46 @@ describe('executor', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('should parse config from `env-var` and `config`', function(done) {
|
||||
var bootInstructions = simpleComponentConfig(
|
||||
{
|
||||
path: '${restApiRoot}',
|
||||
fromConfig: '${DYNAMIC_CONFIG}',
|
||||
fromEnvVar: '${DYNAMIC_ENVVAR}',
|
||||
}
|
||||
);
|
||||
|
||||
// result should get value from config.json
|
||||
bootInstructions.config['DYNAMIC_CONFIG'] = 'FOOBAR-CONFIG';
|
||||
// result should get value from env var
|
||||
process.env.DYNAMIC_ENVVAR = 'FOOBAR-ENVVAR';
|
||||
|
||||
boot.execute(app, bootInstructions);
|
||||
supertest(app).get('/component').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.fromConfig).to.equal('FOOBAR-CONFIG');
|
||||
expect(res.body.fromEnvVar).to.equal('FOOBAR-ENVVAR');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('`env-var` should have precedence over `config`', function(done) {
|
||||
var key = 'DYNAMIC_VARIABLE';
|
||||
var bootInstructions = simpleComponentConfig({
|
||||
path: '${restApiRoot}',
|
||||
isDynamic: '${' + key + '}',
|
||||
});
|
||||
bootInstructions.config[key] = 'should be overwritten';
|
||||
process.env[key] = 'successfully overwritten';
|
||||
|
||||
boot.execute(app, bootInstructions);
|
||||
supertest(app).get('/component').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.isDynamic).to.equal('successfully overwritten');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse multiple config variables', function(done) {
|
||||
boot.execute(app, simpleComponentConfig(
|
||||
{ path: '${restApiRoot}', env: '${env}' }
|
||||
|
@ -594,13 +698,13 @@ describe('executor', function() {
|
|||
|
||||
it('should parse config variables in an object', function(done) {
|
||||
boot.execute(app, simpleComponentConfig(
|
||||
{ info: { path: '${restApiRoot}' } }
|
||||
{ info: { path: '${restApiRoot}' }}
|
||||
));
|
||||
|
||||
supertest(app).get('/component').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.info).to.eql({
|
||||
path: app.get('restApiRoot')
|
||||
path: app.get('restApiRoot'),
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
@ -608,18 +712,17 @@ describe('executor', function() {
|
|||
|
||||
it('should parse config variables in a nested object', function(done) {
|
||||
boot.execute(app, simpleComponentConfig(
|
||||
{ nested: { info: { path: '${restApiRoot}' } } }
|
||||
{ nested: { info: { path: '${restApiRoot}' }}}
|
||||
));
|
||||
|
||||
supertest(app).get('/component').end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.nested).to.eql({
|
||||
info: { path: app.get('restApiRoot') }
|
||||
info: { path: app.get('restApiRoot') },
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('calls function exported by boot/init.js', function() {
|
||||
|
@ -627,7 +730,7 @@ describe('executor', function() {
|
|||
'module.exports = function(app) { app.fnCalled = true; };');
|
||||
|
||||
delete app.fnCalled;
|
||||
boot.execute(app, someInstructions({ files: { boot: [file] } }));
|
||||
boot.execute(app, someInstructions({ files: { boot: [file] }}));
|
||||
expect(app.fnCalled, 'exported fn was called').to.be.true();
|
||||
});
|
||||
|
||||
|
@ -642,33 +745,33 @@ describe('executor', function() {
|
|||
sourceFile: pushNamePath,
|
||||
config: {
|
||||
phase: 'initial',
|
||||
params: 'initial'
|
||||
}
|
||||
params: 'initial',
|
||||
},
|
||||
},
|
||||
{
|
||||
sourceFile: pushNamePath,
|
||||
config: {
|
||||
phase: 'custom',
|
||||
params: 'custom'
|
||||
}
|
||||
params: 'custom',
|
||||
},
|
||||
},
|
||||
{
|
||||
sourceFile: pushNamePath,
|
||||
config: {
|
||||
phase: 'routes',
|
||||
params: 'routes'
|
||||
}
|
||||
params: 'routes',
|
||||
},
|
||||
},
|
||||
{
|
||||
sourceFile: pushNamePath,
|
||||
config: {
|
||||
phase: 'routes',
|
||||
enabled: false,
|
||||
params: 'disabled'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
params: 'disabled',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
|
||||
supertest(app)
|
||||
|
@ -682,7 +785,6 @@ describe('executor', function() {
|
|||
});
|
||||
|
||||
it('configures middleware using shortform', function(done) {
|
||||
|
||||
boot.execute(app, someInstructions({
|
||||
middleware: {
|
||||
middleware: [
|
||||
|
@ -691,11 +793,11 @@ describe('executor', function() {
|
|||
fragment: 'static',
|
||||
config: {
|
||||
phase: 'files',
|
||||
params: path.join(__dirname, './fixtures/simple-app/client/')
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
params: path.join(__dirname, './fixtures/simple-app/client/'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
|
||||
supertest(app)
|
||||
|
@ -725,8 +827,8 @@ describe('executor', function() {
|
|||
it('configures components', function() {
|
||||
appdir.writeConfigFileSync('component-config.json', {
|
||||
'./components/test-component': {
|
||||
option: 'value'
|
||||
}
|
||||
option: 'value',
|
||||
},
|
||||
});
|
||||
|
||||
appdir.writeFileSync('components/test-component/index.js',
|
||||
|
@ -743,7 +845,7 @@ describe('executor', function() {
|
|||
|
||||
it('disables component when configuration is not set', function() {
|
||||
appdir.writeConfigFileSync('component-config.json', {
|
||||
'./components/test-component': false
|
||||
'./components/test-component': false,
|
||||
});
|
||||
|
||||
appdir.writeFileSync('components/test-component/index.js',
|
||||
|
@ -758,10 +860,10 @@ describe('executor', function() {
|
|||
|
||||
it('disable component if overrided by production configuration', function() {
|
||||
appdir.writeConfigFileSync('component-config.json', {
|
||||
'./components/test-component': {}
|
||||
'./components/test-component': {},
|
||||
});
|
||||
appdir.writeConfigFileSync('component-config.production.json', {
|
||||
'./components/test-component': null
|
||||
'./components/test-component': null,
|
||||
});
|
||||
|
||||
appdir.writeFileSync('components/test-component/index.js',
|
||||
|
@ -785,11 +887,11 @@ describe('executor', function() {
|
|||
sourceFile: passportPath,
|
||||
fragment: 'initialize',
|
||||
config: {
|
||||
phase: 'auth:before'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
phase: 'auth:before',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
|
||||
supertest(app)
|
||||
|
@ -809,6 +911,132 @@ describe('executor', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when booting with lazy connect', function() {
|
||||
var SAMPLE_INSTRUCTION = someInstructions({
|
||||
dataSources: {
|
||||
lazyConnector: {
|
||||
connector: 'testLazyConnect',
|
||||
name: 'lazyConnector',
|
||||
},
|
||||
},
|
||||
});
|
||||
var connectTriggered = true;
|
||||
|
||||
beforeEach(function() {
|
||||
app.connector('testLazyConnect', {
|
||||
initialize: function(dataSource, callback) {
|
||||
if (dataSource.settings.lazyConnect) {
|
||||
connectTriggered = false;
|
||||
} else {
|
||||
connectTriggered = true;
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger connect with ENV undefined', function(done) {
|
||||
delete process.env.LB_LAZYCONNECT_DATASOURCES;
|
||||
boot.execute(app, SAMPLE_INSTRUCTION, function() {
|
||||
expect(connectTriggered).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not trigger connect with ENV true', function(done) {
|
||||
process.env.LB_LAZYCONNECT_DATASOURCES = 'true';
|
||||
boot.execute(app, SAMPLE_INSTRUCTION, function() {
|
||||
expect(connectTriggered).to.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger connect with ENV false', function(done) {
|
||||
process.env.LB_LAZYCONNECT_DATASOURCES = 'false';
|
||||
boot.execute(app, SAMPLE_INSTRUCTION, function() {
|
||||
expect(connectTriggered).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger connect with ENV 0', function(done) {
|
||||
process.env.LB_LAZYCONNECT_DATASOURCES = '0';
|
||||
boot.execute(app, SAMPLE_INSTRUCTION, function() {
|
||||
expect(connectTriggered).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('dynamic configuration for datasources.json', function() {
|
||||
beforeEach(function() {
|
||||
delete process.env.DYNAMIC_HOST;
|
||||
delete process.env.DYNAMIC_PORT;
|
||||
});
|
||||
|
||||
it('should convert dynamic variable for datasource', function(done) {
|
||||
var datasource = {
|
||||
mydb: {
|
||||
host: '${DYNAMIC_HOST}',
|
||||
port: '${DYNAMIC_PORT}',
|
||||
},
|
||||
};
|
||||
var bootInstructions = { dataSources: datasource };
|
||||
|
||||
process.env.DYNAMIC_PORT = '10007';
|
||||
process.env.DYNAMIC_HOST = '123.321.123.132';
|
||||
|
||||
boot.execute(app, someInstructions(bootInstructions), function() {
|
||||
expect(app.datasources.mydb.settings.host).to.equal('123.321.123.132');
|
||||
expect(app.datasources.mydb.settings.port).to.equal('10007');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should resolve dynamic config via app.get()', function(done) {
|
||||
var datasource = {
|
||||
mydb: { host: '${DYNAMIC_HOST}' },
|
||||
};
|
||||
var bootInstructions = {
|
||||
config: { DYNAMIC_HOST: '127.0.0.4' },
|
||||
dataSources: datasource,
|
||||
};
|
||||
boot.execute(app, someInstructions(bootInstructions), function() {
|
||||
expect(app.get('DYNAMIC_HOST')).to.equal('127.0.0.4');
|
||||
expect(app.datasources.mydb.settings.host).to.equal(
|
||||
'127.0.0.4');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should take ENV precedence over config.json', function(done) {
|
||||
process.env.DYNAMIC_HOST = '127.0.0.2';
|
||||
var datasource = {
|
||||
mydb: { host: '${DYNAMIC_HOST}' },
|
||||
};
|
||||
var bootInstructions = {
|
||||
config: { DYNAMIC_HOST: '127.0.0.3' },
|
||||
dataSources: datasource,
|
||||
};
|
||||
boot.execute(app, someInstructions(bootInstructions), function() {
|
||||
expect(app.get('DYNAMIC_HOST')).to.equal('127.0.0.3');
|
||||
expect(app.datasources.mydb.settings.host).to.equal('127.0.0.2');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('empty dynamic conf should resolve as `undefined`', function(done) {
|
||||
var datasource = {
|
||||
mydb: { host: '${DYNAMIC_HOST}' },
|
||||
};
|
||||
var bootInstructions = { dataSources: datasource };
|
||||
|
||||
boot.execute(app, someInstructions(bootInstructions), function() {
|
||||
expect(app.get('DYNAMIC_HOST')).to.be.undefined();
|
||||
expect(app.datasources.mydb.settings.host).to.be.undefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function simpleMiddlewareConfig(phase, paths, params) {
|
||||
|
@ -819,7 +1047,7 @@ function simpleMiddlewareConfig(phase, paths, params) {
|
|||
|
||||
var config = {
|
||||
phase: phase,
|
||||
params: params
|
||||
params: params,
|
||||
};
|
||||
|
||||
if (paths) config.paths = paths;
|
||||
|
@ -831,9 +1059,9 @@ function simpleMiddlewareConfig(phase, paths, params) {
|
|||
{
|
||||
sourceFile: path.join(__dirname, './fixtures/simple-middleware.js'),
|
||||
config: config,
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -842,9 +1070,9 @@ function simpleComponentConfig(config) {
|
|||
components: [
|
||||
{
|
||||
sourceFile: path.join(__dirname, './fixtures/simple-component.js'),
|
||||
config: config
|
||||
}
|
||||
]
|
||||
config: config,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -869,12 +1097,12 @@ function someInstructions(values) {
|
|||
var result = {
|
||||
config: values.config || {},
|
||||
models: values.models || [],
|
||||
dataSources: values.dataSources || { db: { connector: 'memory' } },
|
||||
dataSources: values.dataSources || { db: { connector: 'memory' }},
|
||||
middleware: values.middleware || { phases: [], middleware: [] },
|
||||
components: values.components || [],
|
||||
files: {
|
||||
boot: []
|
||||
}
|
||||
boot: [],
|
||||
},
|
||||
};
|
||||
|
||||
if (values.env)
|
||||
|
@ -898,6 +1126,6 @@ function envAppInstructions() {
|
|||
fs.copySync(ENV_APP, appdir.PATH);
|
||||
return boot.compile({
|
||||
appRootDir: appdir.PATH,
|
||||
env: 'test'
|
||||
env: 'test',
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015,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
|
||||
|
||||
var loopback = require('loopback');
|
||||
var boot = require('../../../');
|
||||
|
||||
|
@ -5,5 +10,5 @@ var app = module.exports = loopback();
|
|||
|
||||
boot(app, {
|
||||
appId: 'browserApp2',
|
||||
appRootDir: __dirname
|
||||
appRootDir: __dirname,
|
||||
});
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = function(Robot) {
|
||||
Robot.settings._customized = 'Robot';
|
||||
Robot.base.settings._customized = 'Robot';
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var loopback = require('loopback');
|
||||
var boot = require('../../../');
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = function(app) {
|
||||
app.set('custom-key', 'custom-value');
|
||||
};
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = function(app, options) {
|
||||
app.dummyComponentOptions = options;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// Copyright IBM Corp. 2015,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
|
||||
|
||||
module.exports = function(Model, options) {
|
||||
|
||||
Model.timeStampsMixin = true;
|
||||
|
||||
};
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = function(Customer) {
|
||||
Customer.settings._customized = 'Customer';
|
||||
Customer.base.settings._customized = 'Base';
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
process.bootFlags.push('barLoadedInTest');
|
||||
module.exports = function(app, callback) {
|
||||
callback();
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015,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
|
||||
|
||||
var framework = {
|
||||
initialize: function(passport) {
|
||||
return function(req, res, next) {
|
||||
|
@ -5,7 +10,7 @@ var framework = {
|
|||
res.setHeader('passport', 'initialized');
|
||||
next();
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var Passport = function() {
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
process.bootFlags.push('barLoaded');
|
||||
module.exports = function(app, callback) {
|
||||
process.bootFlags.push('barStarted');
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
process.bootFlags.push('barSyncLoaded');
|
||||
module.exports = function(app) {
|
||||
process.bootFlags.push('barSyncExecuted');
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = function(app, cb) {
|
||||
if (app.booting)
|
||||
process.bootingFlagSet = true;
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
process.bootFlags.push('fooLoaded');
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
exports.myMiddleware = function(name) {
|
||||
return function(req, res, next) {
|
||||
req._names = req._names || [];
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
/**
|
||||
* Exporting a middleware as a property of the main module
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
module.exports = function(loopbackApp, params) {
|
||||
// Copyright IBM Corp. 2015,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
|
||||
|
||||
module.exports = function(loopbackApp, params) {
|
||||
loopbackApp.use('/component', function(req, res, next) {
|
||||
res.send(params);
|
||||
});
|
||||
|
||||
};
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = function(params) {
|
||||
return function(req, res, next) {
|
||||
res.send(params);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// 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
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs-extra');
|
||||
var extend = require('util')._extend;
|
||||
|
@ -27,8 +32,8 @@ appdir.createConfigFilesSync = function(appConfig, dataSources, models) {
|
|||
dataSources = extend({
|
||||
db: {
|
||||
connector: 'memory',
|
||||
defaultForType: 'db'
|
||||
}
|
||||
defaultForType: 'db',
|
||||
},
|
||||
}, dataSources);
|
||||
appdir.writeConfigFileSync ('datasources.json', dataSources);
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015,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
|
||||
|
||||
var vm = require('vm');
|
||||
|
||||
function createContext() {
|
||||
|
@ -8,14 +13,14 @@ function createContext() {
|
|||
|
||||
localStorage: {
|
||||
// used by `debug` module
|
||||
debug: process.env.DEBUG
|
||||
debug: process.env.DEBUG,
|
||||
},
|
||||
|
||||
// used by DataSource.prototype.ready
|
||||
setTimeout: setTimeout,
|
||||
|
||||
// used by `debug` module
|
||||
document: { documentElement: { style: {} } },
|
||||
document: { documentElement: { style: {}}},
|
||||
|
||||
// used by `debug` module
|
||||
navigator: { userAgent: 'sandbox' },
|
||||
|
@ -39,9 +44,9 @@ function createContext() {
|
|||
_logs: {
|
||||
log: [],
|
||||
warn: [],
|
||||
error: []
|
||||
error: [],
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// `window` is used by loopback to detect browser runtime
|
||||
|
@ -52,9 +57,10 @@ function createContext() {
|
|||
exports.createContext = createContext;
|
||||
|
||||
function printContextLogs(context) {
|
||||
for (var k in context.console._logs) {
|
||||
var k, ix; // see https://github.com/eslint/eslint/issues/5744
|
||||
for (k in context.console._logs) {
|
||||
var items = context.console._logs[k];
|
||||
for (var ix in items) {
|
||||
for (ix in items) {
|
||||
console[k].apply(console, items[ix]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2015. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
var fs = require('fs');
|
||||
var sandbox = require('./sandbox');
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
module.exports = function(name) {
|
||||
return function(req, res, next) {
|
||||
req._names = req._names || [];
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Copyright IBM Corp. 2014. All Rights Reserved.
|
||||
// Node module: loopback-boot
|
||||
// This file is licensed under the MIT License.
|
||||
// License text available at https://opensource.org/licenses/MIT
|
||||
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
|
||||
|
|
Loading…
Reference in New Issue