Port can't be number checked to support iisnode. Using a parseInt()
or number isNumber function won't work if we want to support iisnode
which uses named pipes for ports (ex. \\.\pipe\mypipe)
Extend the options argument of boot/compile to allow the developer
to supply custom model definitions (to replace the result of
findModelDefinitions). Together with the existing options.models,
it allows to specify all model-related data and still use the benefits
which loopback-boot provides (most notably loading models in order
defined by inheritance, i.e. base models are loaded before models that
are extending them).
Use the global `isFinite` function to find the first valid port
number. This is the same behaviour as `_.isFinite` in lodash@2.x.
As a result, only values that are a valid number are accepted, e.g.
"0" is accepted but "0xy" is not.
- Ensure `app.booting` is initially `undefined`
- Ensure `app.booting` is set to true during boot execution
- Ensure `app.booting` is set to false upon boot completion
This prevents an occurence where an error is completely swallowed if a script
required by loopback-boot has a bad require() call. The script is never ran
but execution continues.
Load configuration of components from `component-config`
and configure all components as specified.
Sample JSON:
{
"loopback-component-foobar": {
"option1": "value1",
"option2": "value2"
}
}
The component is expected to export the following function:
module.exports = function(app, options) { /* ... */ };
Remove duplicated entries in the array of boot scripts to run.
Because the bootDirs defaults to process.cwd(), if the user manually
includes scripts in the same directory, without specifying a bootDir,
those scripts will be included multiple times.
Introduce a convention for specifying relative paths in middleware
params: values prefixed with `$!` and starting with `./` or `../`
are resolved relatively to `middleware.json`.
Example:
{
"files": {
"loopback#static": {
"params": "$!../client"
},
"loopback#static": {
"params": "$!./public"
}
}
}
When the middleware name (path) is in the format {module}#{filename},
loopback-boot resolves the path by trying multiple locations and
using the first one that exists:
- {module} and check the {filename} property of the exports
-> e.g. loopback.rest
- {module}/server/middleware/{filename}
-> e.g. loopback/server/middleware/rest
- {module}/middleware/{filename}
-> e.g. loopback/middleware/rest
Values in any other format will bypass this resolution algorithm and
they will be used in the original form:
- a full path in a module: loopback/server/middleware/rest
- a relative path: ./middleware/custom, ./custom, ../logger
- an absolute path: /usr/local/lib/node_modules/compression
Sample JSON:
{
"routes:before": {
"morgan": {
"params": ["dev"]
}
},
"routes": {
"loopback/server/middleware/rest": {
}
},
"subapps": {
"./adminer": {
},
}
}
The JSON file can be customized using the usual conventions:
- middleware.local.{js|json}
- middleware.{env}.{js|json}
It is also possible to mount the same middleware in the same phase
multiple times with different configuration.
Example config:
{
"auth": {
"oauth2": [
{
"params": "first"
},
{
"params": "second"
}
]
},
});
Load models for any filetypes registered in require.extensions.
- Server side coffee-script requires a `require('coffee-script/register');`
- Client side coffee-script requires Coffeeify.
Interpret model sources in the same way how `require.resolve`
interprets the path:
- values starting with `./` and `../` are relative to the file
where they are specified
- other values are relative to node modules folders
This way it's possible to specify a source `loopback/common/models`
and have it resolved to whatever place the loopback is installed.
LoopBack built-in models are special: they follow the loopback-boot
structure and provide `common/models/{name}.json` files, but they are
also automatically loaded (created) by loopback.
This change modifies `executor` to recognize built-in models and do not
redefine them.
Simplify the contract for functions exported by `models/*.js` files
by removing the second argument `Base`. The base class can be accessed
using `ModelCtor.base`.
An updated example of a model js file:
```js
module.exports = function(Customer) {
Customer.setup = function() {
Customer.base.setup.apply(this, arguments);
// etc.
};
};
```
When executor passes the instruction to loopback methods,
loopback modifies the data. Since we are loading the data using
`require` such changes affects also code that calls
`require` for one of the instructions files.
This change adds a deep clone step to prevent this issue.