module:app
- Description:
The primary application module containing all config options and common functions
- Source:
Members
(static) args :Array.<ConfigOptions>
- Source:
- Default Value:
[ { "name": "cap-(.+)", "type": "int", "strip": "cap-", "sametype": 1, "descr": "Capability parameters" }, { "name": "log", "type": "callback", "callback": "", "descr": "", "pass": 2 }, { "name": "log-options", "type": "map", "empty": 1, "ephemeral": 1, "onupdate": "", "descr": "Update logger options, the format is a map: name:val,...", "pass": 1, "env": "BKJS_LOG_OPTIONS" }, { "name": "log-file", "type": "callback", "callback": "", "descr": "Log to a file, if not specified used default logfile, disables syslog", "pass": 1, "env": "BKJS_LOG_FILE" }, { "name": "log-ignore", "type": "regexp", "obj": "logInspect", "strip": {}, "nocamel": 1, "descr": "Regexp with property names which must not be exposed in the log when using custom logger inspector" }, { "name": "log-inspect", "type": "callback", "callback": "setLogInspect", "descr": "Install custom logger inspector instead of util.inspect: 'json' - JSON output, 1|true - lib.inspect, 0 - util.inspect", "pass": 1, "env": "BKJS_LOG_INSPECT" }, { "name": "log-inspect-options", "type": "map", "obj": "log-inspect", "merge": 1, "replace": "", "descr": "Options for the logger using lib.inspect" }, { "name": "log-filter", "type": "callback", "callback": "", "descr": "Enable debug filters, format is: label,... to enable, and !label,... to disable. First 2 arguments are used by debug filter in logger.debug", "pass": 1, "example": "//To log all debugging api and queries: as first/second args\napp-log-filter = api,query:" }, { "name": "log-clear", "type": "bool", "ephemeral": 1, "onupdate": "", "descr": "Clear all log filters", "pass": 1 }, { "name": "syslog", "type": "callback", "callback": "", "descr": "Log messages to syslog, pass 0 to disable, 1 or url (tcp|udp|unix):[//host:port][/path]?[facility=F][&tag=T][&retryCount=N][&bsd=1][&rfc5424=1][&rfc3164=1]...", "pass": 1, "env": "BKJS_SYSLOG" }, { "name": "console", "type": "callback", "callback": "", "descr": "All logging goes to the console resetting all previous log related settings, this is used in the development mode mostly", "pass": 1 }, { "name": "home", "type": "callback", "callback": "setHome", "descr": "Specify home directory for the server, the server will try to chdir there or exit if it is not possible, the directory must exist", "pass": 2 }, { "name": "config", "type": "path", "descr": "Name of the config file to be loaded, can be relative or absolute path", "pass": 1 }, { "name": "tmp-dir", "type": "path", "descr": "Path where to keep temp files" }, { "name": "path-web", "type": "path", "array": 1, "obj": "path", "descr": "Add a path where to keep web pages and other static files to be served by the web servers" }, { "name": "path-modules", "type": "path", "array": 1, "obj": "path", "descr": "Add a path from where to load modules, these are the backendjs modules but in the same format and same conventions as regular node.js modules. The modules can load any other files or directories, this is just an entry point", "pass": 1 }, { "name": "salt", "type": "callback", "callback": "", "descr": "Set random or specific salt value to be used for consistent suuid generation", "pass": 1 }, { "name": "version", "descr": "Set app name/version explicitely and skip reading it from the package.json", "pass": 1 }, { "name": "roles", "type": "list", "obj": "env", "descr": "Additional config roles, a shortcut for app-env-roles", "example": "app-roles = redis, dynamodb", "pass": 1 }, { "name": "env-([a-z0-9_-]+)", "obj": "env", "make": "$1", "camel": "-", "autotype": "", "descr": "Set runtime env properties explicitly: tag, region, zone, roles, ...", "pass": 1, "example": "app-env-roles = dev,web\napp-env-tag = api" }, { "name": "daemon", "type": "none", "descr": "Daemonize the process, go to the background, can be specified only in the command line" }, { "name": "shell", "type": "none", "descr": "Run command line shell, load the backend into the memory and prompt for the commands, can be specified only in the command line" }, { "name": "server", "type": "none", "descr": "Start the server server, can be specified only in the command line, this process handles job schedules and starts Web server in separate process, keeps track of failed processes and restarts them" }, { "name": "worker", "type": "bool", "descr": "Set this process as a worker even it is actually a primary, this skips some initializations" }, { "name": "no", "type": "callback", "callback": "", "descr": "List of subsystems to disable instead of using many inidividual -no-NNN parameters", "pass": 1 }, { "name": "no-([a-z]+)", "type": "callback", "callback": "", "strip": "no-", "nocamel": 1, "descr": "Do not start or disable a service, server, web, jobs, ipc, db, dbconf, watch, modules, packages, configure", "pass": 1 }, { "name": "ok-(.+)", "type": "callback", "callback": "", "strip": "ok-", "nocamel": 1, "descr": "Enable disabled service, opposite of -no", "pass": 1 }, { "name": "repl-port-([a-z]+)$", "type": "number", "obj": "repl", "make": "$1Port", "min": 1001, "descr": "Base REPL port for process role (server, web, worker), if specified it initializes REPL in the processes, for workers the port is computed by adding a worker id to the base port, for example if specified `-repl-port-web 2090` then a web worker will use any available 2091,2092..." }, { "name": "repl-([a-z]+)", "obj": "repl", "type": "auto", "descr": "REPL settings: listen, file, size" }, { "name": "import", "type": "list", "array": 1, "push": 1, "descr": "NPM packages to load on startup, the modules, views, web subfolders from the package will be added automatically to the system paths, modules will be loaded if present, the bkjs.conf will be parsed if present", "pass": 1 }, { "name": "modules-include", "obj": "modules", "type": "regexp", "descr": "Modules to load only, the whole path is checked", "pass": 1, "env": "BKJS_INCLUDE_MODULES" }, { "name": "modules-exclude", "obj": "modules", "type": "regexp", "descr": "Modules not to load, the whole path is checked", "pass": 1, "env": "BKJS_EXCLUDE_MODULES" }, { "name": "modules-depth", "obj": "modules", "type": "int", "descr": "How deep to go looking for modules, it uses lib.findFileSync to locate all .js files", "pass": 1 }, { "name": "modules-methods-(.+)", "obj": "modules", "make": "$1", "type": "regexp", "nocamel": 1, "descr": "Modules that allowed to run methods by name, useful to restrict configure methods", "example": "-app-modules-methods-configureMiddleware myapp", "pass": 1 }, { "name": "host-name", "type": "callback", "callback": "setHost", "descr": "Hostname/domain to use for communications, default is current domain of the host machine" }, { "name": "workers", "type": "int", "descr": "Max number of web processes to launch, -1 disables workers, 0 means launch as many as the CPUs available`" }, { "name": "worker-cpu-factor", "type": "real", "min": 0, "descr": "A number to multiply the number of CPUs available to make the total number of workers to launch, only used if `workers` is 0" }, { "name": "worker-args", "type": "list", "vreplace": "", "descr": "Node arguments for workers, job and web processes, for passing v8 options, use %20 for spaces" }, { "name": "worker-delay", "type": "int", "descr": "Delay in milliseconds for a web worker before it will start accepting requests, for cases when other dependencies may take some time to start" }, { "name": "no-restart", "type": "bool", "descr": "Do not restart any workers" }, { "name": "stop-on-error", "type": "bool", "descr": "Exit the process on any error when loading modules, for dev purposes", "pass": 1 }, { "name": "exit-timeout", "type": "int", "descr": "Duration in ms to delay process exit in app.exit" }, { "name": "exit-on-empty", "type": "int", "descr": "Duration in ms to exit the server process after last worker terminated" }, { "name": "pid-file", "descr": "Server process pid file" }, { "name": "err-file", "descr": "Server error log file in daemon mode" } ]
(static) config :string
- Description:
Config file to load on startup, defaults to bkjs.conf
- Source:
- Default Value:
- bkjs.conf
(static) ctime :number
- Description:
time in ms when the module started
- Source:
(static) cwd :string
- Description:
always current directory on start
- Source:
(static) env :object
- Description:
Current ruintime env properties and instance/container attributes gathered by other modules
- Source:
Properties:
| Name | Type | Description |
|---|---|---|
roles |
string | Additional roles to use for configuration purposes, set via BKJS_ROLES |
tag |
string | Instance/container tag set manually, via BKJS_TAG or derived from AWS tags |
id |
string | hostname or EC2 instance id |
type |
string | aws if running in AWS |
worker_id |
string | set from cluster.worker_id |
image |
string | EC2 image id |
instance_type |
string | EC2 instance type |
container |
string | ECS container name |
container_id |
string | ECS container id |
task_id |
string | ECS container task id |
ip |
string | EC2/ECS private IP address |
region |
string | AWS region |
accountId |
string | AWS account id |
zone |
string | AWS availability zone |
(static) home :string
- Description:
home folder, from config or env.BKJS_HOME
- Source:
(static) host :string
- Description:
machine host name
- Source:
- Default Value:
- localhost
(static) isMainThread :boolean
- Description:
Is true if this code is not running inside of a Worker thread.
- Source:
(static) isPrimary :boolean
- Description:
is true if the process is primary
- Source:
(static) isWorker :boolean
- Description:
is true if the process is a worker process
- Source:
(static) logInspect :object
- Description:
options for inspect when used by the logger, supports options for module:lib.inspect
- Source:
(static) mimeTypes :object
- Description:
List of basic mime types
- Source:
(static) modules :object
- Description:
modules config
- Source:
(static) packages :object
- Description:
imported packages
- Source:
(static) path :object
- Description:
path collections from config or imported packages
- Source:
- Default Value:
{ "web": "", "modules": "" }
Properties:
| Name | Type | Description |
|---|---|---|
path.web |
Array.<string> | list of all folders with public web assets |
path.modules |
Array.<string> | folders with modules to load |
(static) role :string
- Description:
the primary proccess role, one of: node, watcher, server, web, worker
- Source:
(static) version :string
- Description:
Application name/version from package.json or manually set
- Source:
(static) workers :int
- Description:
worker processes to start
- Source:
- Default Value:
- 1
(inner) ipaddr :string
- Description:
host IP address, non-local interface
- Source:
(inner) repl :object
- Description:
REPL settings
- Source:
Properties:
| Name | Type | Description |
|---|---|---|
bind |
string | listen address |
file |
string | file with history |
size |
string | how much of history to load |
serverPort |
string | server listen port |
webPort |
string | web worker listen port |
workerPort |
string | job worker listen port |
Methods
(static) addModule(any)
- Description:
Adds reference to the objects in the core for further access. This is used in the core to register all internal modules and makes it available in the shell and in the module:modules object.
If module name starts with underscore it is silently ignored. Empty names are not allowed and reported.
Module name can contain dots, meaning to place the module under hierarchy of namespaces. Modules can be placed under existing modules, the context is still separate for each module.
Also this is used when creating modular backend application by separating the logic into different modules, by registering such modules with the core it makes the module a first class citizen in the backendjs core and exposes all the callbacks and methods.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
any |
Array.<object> | modules to add |
Examples
const { modules } = require("backendjs");
const mymod = { name: "billing.invoices", request: () => { ... } }
app.addModule(mymod);
modules.billing.invoices.request({ ... });
The module below will register API routes and some methods
const { api, core } = require("backendjs");
const mymod = { name: "mymod" }
exports.module = mymod;
app.addModule(mymod);
mymod.configureMiddleware = function(options, callback) {
api.app.all("/mymod", (context) => {
context.json({});
});
}
In the main app.js just load it and the rest will be done automatically, i.e. routes will be created ...
const mymod = require("./mymod.js");
Running the shell will make the object **mymod** available
./app.sh -shell
> mymod
{ name: "mymod" }
(async, static) ainit(optionsopt) → {object}
- Description:
Async version of module:app.init
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
options |
object |
<optional> |
Returns:
| Type | Description |
|---|---|
| object |
in format { err } |
(async, static) arunMethods() → {undefined|Error|object}
- Description:
Async version of module:app.runMethods
- Source:
Returns:
| Type | Description |
|---|---|
| undefined | Error | object |
|
(async, static) astop()
- Description:
Async version of app.stop
- Source:
(static) checkConfig(callbackopt) → {none}
- Description:
Reload runtime config from the DB
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
callback |
function() |
<optional> |
a function to call after the check |
Returns:
| Type | Description |
|---|---|
| none |
(static) createRepl()
- Description:
Create REPL interface with all modules available
- Source:
(static) describeArgs(args) → {object}
- Description:
Add custom config parameters to be understood and processed by the config parser
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
|
string | a module name to add these params to |
args |
Array.<object> | a list of objects in the format: { name: N, type: T, descr: D, min: M, max: M, array: B... }, all except name are optional. |
Returns:
| Type | Description |
|---|---|
| object |
a module object where args added or undefined if not |
Example
app.describeArgs("api", [ { name: "num", type: "int", descr: "int param" }, { name: "list", array: 1, descr: "list of words" } ]);
app.describeArgs("app", [ { name: "list", array: 1, descr: "list of words" } ]);
(static) exit(optionsopt)
- Description:
Terminates the server process, it is called on SIGTERM signal but can be called manually for graceful shutdown, it runs
shutdown[Role]methods before exiting. if app.exitTimeout defined it is used by default to always delay process exit.
- Source:
Parameters:
| Name | Type | Attributes | Description | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
options |
object |
<optional> |
Properties
|
(static) getExtension(type) → {string|undefined}
- Description:
Return file extension for givem MIME type
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
type |
string | MIME type |
Returns:
| Type | Description |
|---|---|
| string | undefined |
|
(static) getMimeType(file) → {string|undefined}
- Description:
Return MIME type for given file name
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
file |
string | file name |
Returns:
| Type | Description |
|---|---|
| string | undefined |
|
(static) init(options, callbackopt)
- Description:
Main initialization, must be called prior to perform any actions.
- Source:
Parameters:
| Name | Type | Attributes | Description | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options |
object | options for customization what to init Properties
|
|||||||||||||||||||||||||||||||||
callback |
function() |
<optional> |
called at the end with possible err |
(static) isOk(name, optionsopt)
- Description:
Return true if the given service is not disabled and no property no${name} exists in the options
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
name |
string | service name |
|
options |
object |
<optional> |
(static) killBackend()
- Description:
Kill all backend processes that match name and not the current process
- Source:
(static) loadModules(dir, includeopt, excludeopt) → {Array.<string>}
- Description:
Dynamically load services from the specified directory.
The modules are loaded using require as a normal nodejs module but in addition if the module exports init method it is called immediately with options passed as an argument.
This is a synchronous function so it is supposed to be called on startup, not dynamically during a request processing.
System default is to load all *.js files that do not start with underscore.
Only files from top level are loaded by default unless the depth is provided. addModule is called automatically, it uses findFileSync to locate the modules, options depth, **include or exclude can be provided
Each module is put in the top level modules registry by name, the name must be defined as property name, modules with empty name will be ignored.
Module names starting with underscore will not be added to the registry.
If a module name contains dots it means nested hierarchy, all intermediate objects will be created automatically. Nested names allow a better separation of modules and name collisions.
Caution must be taken for module naming, it is possible to override any default bkjs module which will result in unexpected behaviour
The following module properties are reserved and used by the backendjs:
- name - module name
- deps - dependent module name
mod- place after the module mod-modto be placed before module mod-- a single - means place at the beginning*a single * means place at the end
- args - list of config parameters
- tables - table definitions
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
dir |
string | name of directory containing modules |
|
options.depth |
number |
<optional> |
how deep to look for modules |
include |
regexp |
<optional> |
regexp to match files or paths to load only, default is .js$ |
exclude |
regexp |
<optional> |
regexp what files or paths to exlude, default is ^_ |
Returns:
| Type | Description |
|---|---|
| Array.<string> |
a list of all loaded module names |
Example
// load all modules from the local relative directory
app.loadModules("modules")
(static) loadPackages(list, options) → {String}
- Description:
Load NPM packages and auto configure paths from each package. bkjs.conf in the root of the package will be loaded as a config file.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
list |
String | Array | list of packages to load |
options |
Object | an object with optional parameters |
Returns:
| Type | Description |
|---|---|
| String |
all config files for all packages concatenated |
(static) origin() → {string}
- Description:
Return app instance signature to be used as tracking origin or source in the logs or events. formatted as:
role:process pid:IP address:tag:current time
- Source:
Returns:
| Type | Description |
|---|---|
| string |
(static) parseArgs(argv, pass, fileopt)
- Description:
Parse command line arguments
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
argv |
Array.<string> | a list of config parameters in the form [ "-param", "value" ,...] |
|
pass |
int | a number representing a pass phase |
|
file |
string |
<optional> |
file name where parameters came from |
(static) parseConfig(data, pass, fileopt)
- Description:
Parse and apply config lines for the file or other place, uses module:lib.parseConfig.
The following properties are exposed only for conditions in sections:
home, cwd, role, roles, tag, env, version, config, arch, host, platform, process- env contains all properties set via
app-env-.... - process is an object: { env, pid, uid, title, arch, platform, version }
- env contains all properties set via
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
data |
string | data from a config file |
|
pass |
int | a number representing a pass phase |
|
file |
string |
<optional> |
file name where parameters came from |
Example
[instance.type=]
db-pool=sqlite
db-sqlite-pool=/tmp/test
[instance.type=aws]
db-pool=dynamodb
db-config=dynamodb
db-dynamodb-pool=default
[process.platform=linux]
api.reuse-port=1
(static) processArg(options)
- Description:
Process a single argument
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
options |
object | are supposed to be returned by _findArg or prepared accordingly |
(static) processArgs(mod, argv, pass, fileopt)
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
mod |
object | run for module's args only |
|
argv |
Array.<string> | a list of config parameters in the form [ "-param", "value" ,...] |
|
pass |
int | a number representing a pass phase |
|
file |
string |
<optional> |
file name where parameters came from |
(static) processEnvArgs()
- Description:
Process parameters from env variables
- Source:
(static) runMethod(mod, name, data, options, callbackopt) → {undefined}
- Description:
Run a method for the given module
- Source:
Parameters:
| Name | Type | Attributes | Description | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
mod |
string | module name |
|||||||||||||||||||||
name |
string | method name |
|||||||||||||||||||||
data |
any | object | data for the method |
|||||||||||||||||||||
options |
object | additional options to control method execution Properties
|
|||||||||||||||||||||
callback |
function() |
<optional> |
function to be called at the end |
Returns:
| Type | Description |
|---|---|
| undefined |
(static) runMethods(name, data, optionsopt, callbackopt)
- Description:
Run a method for every module, a method must conform to the following signature: function(options, callback) and call the callback when finished. The callback second argument will be the parameters passed to each method, the options if provided can specify the conditions or parameters which wil be used by the runMethods** only.
The modules's deps property defines the position in the modules list and thus determines the order of calling methods. The property contains other module name this module depend on, i.e. it must be placed after it. if deps starts with - it means place this module before the other module. A single - means place it at the beginningh of the list. A single * means place it at the end of the list.
- Source:
Parameters:
| Name | Type | Attributes | Description | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
name |
string | method name |
|||||||||
data |
any | specific data passed to methods |
|||||||||
options |
object |
<optional> |
additional options to control method execution Properties
|
||||||||
|
regexp | [options.allowModules] - a regexp of the modules names to be called only |
|||||||||
|
boolean | [options.stopOnError] - on first error stop and return, otherwise all errors are ignored and all modules are processed |
|||||||||
options.stopFilter |
function() |
<optional> |
a function(data, options) that must return true in order to stop execution of other methods |
||||||||
|
string | [options.logger_error] - logger level, if not specified an error with status 200 will be reported with log level 'info' and other errors with level 'error' |
|||||||||
|
object | [options.logger_inspect] - an object with inspect options to override current inspect parameters |
|||||||||
|
array | [options.logger_allow] - a list of properties allowed in the log on error, this is to prevent logging too much or sensitive data |
|||||||||
|
boolean | [options.parallel] - if true run methods for all modules in parallel using lib.forEach |
|||||||||
|
number | [options.concurrency] - if a number greater than 1 run that many methods in parallel using lib.forEachLimit |
|||||||||
|
boolean | [options.sync] - if true treat methods as simple functions without callbacks, methods MUST NOT call the second callback argument but simply return |
|||||||||
|
boolean | [options.direct] - if true call all methods directly otherwise via setImmediate |
|||||||||
callback |
<optional> |
function to be called at the end |
(static) setHome(home)
- Description:
Switch to new home directory, exit if we cannot, this is important for relative paths to work if used, no need to do this in worker because we already switched to home directory in the server and all child processes inherit current directory Important note: If run with combined server or as a daemon then this MUST be an absolute path, otherwise calling it in the spawned web server will fail due to the fact that we already set the home and relative path will not work after that.
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
home |
string | new home directory to chdir |
(static) setHost(hostopt) → {string}
- Description:
Set hostname and domain name
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
host |
string |
<optional> |
new host name to set |
Returns:
| Type | Description |
|---|---|
| string |
|
(static) setLogInspect(valopt)
- Description:
Install internal inspector for the logger, an alternative to the util.inspect
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
val |
string | boolean |
<optional> |
json for JSON output, true for lib.inspect or reset to default |
(static) setRole()
- Description:
Set process and logger role
- Source:
(static) sortModules()
- Description:
Sort modules according to dependencies in deps property.
- Source:
(static) start(options, shell, watch, nowatch, server, noserver, api, worker)
- Description:
Start the application, runs
app.initbefore switching to the requested role. The options can be used to set the role instead of command line args: shell, server, watch, api, worker
- Source:
Parameters:
| Name | Type | Description |
|---|---|---|
options |
object | properties to customize initialization |
shell |
boolean | run the shell process |
watch |
boolean | run the watcher process |
nowatch |
boolean | ignore watcher mode |
server |
boolean | run the main server process with api workers |
noserver |
boolean | ignore server mode |
api |
boolean | run the standalone api process |
worker |
boolean | run the standalone worker process |
(static) startRepl()
- Description:
Start command prompt on TCP socket, context can be an object with properties assigned with additional object to be accessible in the shell
- Source:
(static) stop(optionsopt, callbackopt)
- Description:
Shutdown all services, calls the
shutdownmethod first and thenshutdownRolemethod.
- Source:
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
options |
object |
<optional> |
|
callback |
function() |
<optional> |
(static) watchTmp()
- Description:
Watch temp files and remove files that are older than given number of seconds since now, remove only files that match pattern if given Options properties:
- path - root folder, relative or absolute
- age - number of seconds a file to be older to be deleted, default 1 day
- include - a regexp that specifies only files to be watched
- exclude - a regexp of files to be ignored
- nodirs - if 1 skip deleting directories
- depth - how deep to go, default is 1
- Source: