diff --git a/loopback/index.d.ts b/loopback/index.d.ts new file mode 100644 index 0000000000..acaf91f169 --- /dev/null +++ b/loopback/index.d.ts @@ -0,0 +1,2914 @@ +// Type definitions for Loopback 3.1 +// Project: https://github.com/strongloop/loopback +// Definitions by: Andres D Jimenez +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.1 + +/************************************************ +* * +* LoopBack v3.x API * +* * +************************************************/ + +import * as core from "express-serve-static-core"; + +declare function l(): l.LoopBackApplication; +declare namespace l { + + /** + * The `App` object represents a Loopback application + * The App object extends [Express](expressjs.com/api.html#express) and + * supports Express middleware. See + * [Express documentation](expressjs.com) for details + * ```js + * var loopback = require('loopback'); + * var app = loopback() + * app.get('/', function(req, res){ + * res.send('hello world'); + * }) + * app.listen(3000); + * `` + * @class LoopBackApplication + * @header var app = loopback(); + */ + + // interface ILoopbackAplication extends express.Application { }; + + interface LoopBackApplication extends core.Application { + + start(): void; + + /** + * Register a connector + * When a new data-source is being added via `app.dataSource`, the connector + * name is looked up in the registered connectors first + * Connectors are required to be explicitly registered only for applications + * using browserify, because browserify does not support dynamic require, + * which is used by LoopBack to automatically load the connector module + * @param {string} name Name of the connector, e.g. 'mysql'. + * @param {any} connector Connector object as returne + * by `require('loopback-connector-{name}')` + */ + + connector(name: string, connector: any): void; + + /** + * Define a DataSource + * @param {string} name The data source name + * @param {any} config The data source confi + */ + + dataSource(name: string, config: any): void; + + /** + * Enable app wide authentication + */ + + enableAuth(): void; + + /** + * Listen for connections and update the configured port + * When there are no parameters or there is only one callback parameter, + * the server will listen on `app.get('host')` and `app.get('port')` + * For example, to listen on host/port configured in app config: + * ```js + * app.listen(); + * `` + * Otherwise all arguments are forwarded to `http.Server.listen` + * For example, to listen on the specified port and all hosts, and ignore app config. + * ```js + * app.listen(80); + * `` + * The function also installs a `listening` callback that calls + * `app.set('port')` with the value returned by `server.address().port`. + * This way the port param contains always the real port number, even when + * listen was called with port number 0 + * @param {() => void} [cb] If specified, the callback is added as a listener + * for the server's "listening" event. + * @returns {any} http.Server A node `http.Server` with this application configured + * as the request handle + * listen(cb?: () => void):http.Serve + * + */ + + // listen(port?: number, cb?: () => void): any; + + /** + * Attach a model to the app. The `Model` will be available on the + * `app.models` object + * Example - Attach an existing mode + * ```js + * var User = loopback.User; + * app.model(User) + * ``` + * Example - Attach an existing model, alter some aspects of the model: + * ```js + * var User = loopback.User; + * app.model(User, { dataSource: 'db' }) + * `` + * @param {any|string} Model The model to attach + * @options {any} config The model's configuration + * @property {string|any} dataSource The `DataSource` to which to attach the model + * @property {boolean} [public] Whether the model should be exposed via REST API + * @property {any} [relations] Relations to add/update + * @en + * @returns {any} the model clas + */ + + model(Model: any|string, config: {dataSource: string|any, public?: boolean, relations?: any}): any; + + /** + * Get the models exported by the app. Returns only models defined using `app.model() + * There are two ways to access models + * 1. Call `app.models()` to get a list of all models + * ```js + * var models = app.models() + * models.forEach(function(Model) { + * console.log(Model.modelName); // color + * }); + * ``` + * 2. Use `app.model` to access a model by name. + * `app.models` has properties for all defined models + * The following example illustrates accessing the `Product` and `CustomerReceipt` models + * using the `models` object + * ```js + * var loopback = require('loopback'); + * var app = loopback(); + * app.boot({ + * dataSources: { + * db: {connector: 'memory'} + * } + * }) + * app.model('product', {dataSource: 'db'}); + * app.model('customer-receipt', {dataSource: 'db'}) + * // available based on the given name + * var Product = app.models.Product + * // also available as camelCase + * var product = app.models.product + * // multi-word models are avaiable as pascal cased + * var CustomerReceipt = app.models.CustomerReceipt + * // also available as camelCase + * var customerReceipt = app.models.customerReceipt; + * `` + * @returns {Array} Array of model classes + */ + + models(): any[]; + + /** + * Get all remote objects. + * @returns {any} [Remote objects](apidocs.strongloop.com/strong-remoting/#remoteObjectsoptions). + */ + + remoteObjects(): any; + + /** + * Lazily load a set of [remote objects](apidocs.strongloop.com/strong-remoting/#remoteObjectsoptions). + * + * *NOTE:** Calling `app.remotes()` more than once returns only a single set of remote objects. + * @returns {any} remoteObjects + */ + + remotes(): any; + + /** + * Register a middleware using a factory function and a JSON config + * **Example* + * ```js + * app.middlewareFromConfig(compression, { + * enabled: true, + * phase: 'initial', + * params: { + * threshold: 128 + * } + * }); + * `` + * @param {function} factory The factory function creating a middleware handler. + * Typically a result of `require()` call, e.g. `require('compression')`. + * @options {any} config The configuration. + * @property {string} phase The phase to register the middleware in. + * @property {boolean} [enabled] Whether the middleware is enabled. + * Default: `true`. + * @property {Array|*} [params] The arguments to pass to the factory + * function. Either an Array of arguments, + * or the value of the first argument when the factory expects + * a single argument only. + * @property {Array|string|RegExp} [paths] Optional list of paths limiting + * the scope of the middleware + * @returns {any} this (fluent API + * @header app.middlewareFromConfig(factory, config + */ + + middlewareFromConfig(factory: () => void, config: {phase: string, enabled?: boolean, params?: any[]|any, paths?: any[]|string|RegExp}): any; + + /** + * Register (new) middleware phases. + * + * If all names are new, then the phases are added just before "routes" phase. + * Otherwise the provided list of names is merged with the existing phases + * in such way that the order of phases is preserved + * + * **Examples* + * ```js + * // built-in phases: + * // initial, session, auth, parse, routes, files, fina + * + * app.defineMiddlewarePhases('custom'); + * // new list of phases + * // initial, session, auth, parse, custom, routes, files, fina + * app.defineMiddlewarePhases([ + * 'initial', 'postinit', 'preauth', 'routes', 'subapps' + * ]); + * // new list of phases + * // initial, postinit, preauth, session, auth, parse, custom, + * // routes, subapps, files, final + * `` + * @param {string|string[]} nameOrArray A phase name or a list of phase + * names to add + * @returns {any} this (fluent API + * @header app.defineMiddlewarePhases(nameOrArray + */ + + defineMiddlewarePhases(nameOrArray: string|string[]): any; + + /** + * Register a middleware handler to be executed in a given phase. + * @param {string} name The phase name, e.g. "init" or "routes". + * @param {Array|string|RegExp} [paths] Optional list of paths limiting + * the scope of the middleware. + * string paths are interpreted as expressjs path patterns, + * regular expressions are used as-is. + * @param {function} handler The middleware handler, one of + * `function(req, res, next)` or + * `function(err, req, res, next)` + * @returns {any} this (fluent API + * @header app.middleware(name, handler + */ + + middleware(name: string, paths?: any[]|string|RegExp, handler?: () => void): any; + } + + // interface CookieOptions extends core.CookieOptions { } + // interface Errback extends core.Errback { } + // interface ErrorRequestHandler extends core.ErrorRequestHandler { } + // interface Express extends core.Express { } + // interface Handler extends core.Handler { } + // interface Route extends core.IRoute { } + // interface Routers extends core.IRouter { } + // interface RouterMatcher extends core.IRouterMatcher { } + // interface MediaType extends core.MediaType { } + // interface NextFunction extends core.NextFunction { } + // interface Request extends core.Request { } + // interface RequestHandler extends core.RequestHandler { } + // interface RequestParamHandler extends core.RequestParamHandler { } + // export interface Response extends core.Response { } + // interface Router extends core.Router { } + // interface Send extends core.Send { } + + + /** + * LoopBack core module. It provides static properties and + * methods to create models and data sources. The module itself is a function + * that creates loopback `app`. For example: + * + * ```js + * var loopback = require('loopback'); + * var app = loopback(); + * ``` + * + * @property {string} version Version of LoopBack framework. Static read-only property. + * @property {string} mime + * @property {boolean} isBrowser True if running in a browser environment; false otherwise. Static read-only property. + * @property {boolean} isServer True if running in a server environment; false otherwise. Static read-only property. + * @property {Registry} registry The global `Registry` object. + * @property {string} faviconFile Path to a default favicon shipped with LoopBack. + * Use as follows: `app.use(require('serve-favicon')(loopback.faviconFile));` + * @class loopback + * @header loopback + */ + + class loopback { + + /** Version of LoopBack framework. Static read-only property. */ + version: string; + + /** Mime */ + mime: string; + + /** True if running in a browser environment; false otherwise. Static read-only property. */ + isBrowser: boolean; + + /** True if running in a server environment; false otherwise. Static read-only property. */ + isServer: boolean; + + /** The global `Registry` object. */ + registry: Registry; + + /** Path to a default favicon shipped with LoopBack. + * Use as follows: `app.use(require('serve-favicon')(loopback.faviconFile));` + */ + faviconFile: string; + + /** + * Alter an existing Model class. + * @param {Model} ModelCtor The model constructor to alter. + * @options {any} config Additional configuration to apply + * @property {any} dataSource Attach the model to a dataSource. + * @property {any} [relations] Model relations to add/update + * @header loopback.configureModel(ModelCtor, config + */ + + static configureModel(ModelCtor: Model, config: {dataSource: any, relations?: any}): void; + + /** + * Create a data source with passing the provided options to the connector + * @param {string} name Optional name. + * @options {any} options Data Source options + * @property {any} connector LoopBack connector. + * @property {*} [*] Other connector properties. + * See the relevant connector documentation + */ + + static createDataSource(name: string, options: {connector: any, properties?: any}): void; + + /** + * Create a named vanilla JavaScript class constructor with an attached + * set of properties and options + * This function comes with two variants: + * * `loopback.createModel(name, properties, options)` + * * `loopback.createModel(config) + * In the second variant, the parameters `name`, `properties` and `options` + * are provided in the config object. Any additional config entries are + * interpreted as `options`, i.e. the following two configs are identical + * + * ```js + * { name: 'Customer', base: 'User' } + * { name: 'Customer', options: { base: 'User' } } + * `` + * **Example* + * Create an `Author` model using the three-parameter variant + * ```js + * loopback.createModel( + * 'Author', + * { + * firstName: 'string', + * lastName: 'string' + * }, + * { + * relations: { + * books: { + * model: 'Book', + * type: 'hasAndBelongsToMany' + * } + * } + * } + * ); + * `` + * Create the same model using a config object + * ```js + * loopback.createModel({ + * name: 'Author', + * properties: { + * firstName: 'string', + * lastName: 'string' + * }, + * relations: { + * books: { + * model: 'Book', + * type: 'hasAndBelongsToMany' + * } + * } + * }); + * `` + * @param {string} name Unique name. + * @param {any} properties + * @param {any} options (optional + * @header loopback.createMode + */ + + static createModel(name: string, properties: any, options: any): void; + + /** + * Look up a model class by name from all models created by + * `loopback.createModel()` + * @param {string} modelName The model name + * @returns {Model} The model clas + * @header loopback.findModel(modelName + */ + + static findModel(modelName: string): Model; + + /** + * Look up a model class by name from all models created by + * `loopback.createModel()`. Throw an error when no such model exists + * @param {string} modelName The model name + * @returns {Model} The model clas + * @header loopback.getModel(modelName + */ + + static getModel(modelName: string): Model; + + /** + * Look up a model class by the base model class. + * The method can be used by LoopBack + * to find configured models in models.json over the base model. + * @param {Model} modelType The base model class + * @returns {Model} The subclass if found or the base clas + * @header loopback.getModelByType(modelType + */ + + static getModelByType(modelType: Model): Model; + + /** + * Get an in-memory data source. Use one if it already exists + * @param {string} [name] The name of the data source. + * If not provided, the `'default'` is used + */ + + static memory(name?: string): void; + + + /** + * Add a remote method to a model. + * @param {() => void} fn + * @param {any} options (optional + */ + + static remoteMethod(fn: () => void, options: any): void; + + /** + * Create a template helper + * var render = loopback.template('foo.ejs'); + * var html = render({foo: 'bar'}) + * @param {string} path Path to the template file. + * @returns {() => void + */ + + static template(path: string): void; + + // NOTE*** DEPRECATE in 3.0 + // /** + // * Set the default `dataSource` for a given `type`. + // * @param {string} type The datasource type. + // * @param {any|DataSource} dataSource The data source settings or instance + // * @returns {DataSource} The data source instance. + // * + // * @header loopback.setDefaultDataSourceForType(type, dataSource) + // */ + + // setDefaultDataSourceForType(type: string, dataSource: any|DataSource): DataSource; + + // /** + // * Get the default `dataSource` for a given `type`. + // * @param {string} type The datasource type. + // * @returns {DataSource} The data source instance + // */ + + // getDefaultDataSourceForType(type: string): DataSource; + + // /** + // * Attach any model that does not have a dataSource to + // * the default dataSource for the type the Model requests + // */ + + // autoAttach(): void; + + } + + /** + * Define and reference `Models` and `anys` + * @clas + */ + + class Registry { + + static addACL(acls: any[], acl: any): void; + + /** + * Alter an existing Model class. + * @param {Model} ModelCtor The model constructor to alter. + * @options {any} config Additional configuration to apply + * @property {any} dataSource Attach the model to a dataSource. + * @property {any} [relations] Model relations to add/update + * @header loopback.configureModel(ModelCtor, config + */ + + configureModel(ModelCtor: Model, config: {dataSource: any, relations?: any}): void; + + /** + * Create a data source with passing the provided options to the connector + * @param {string} name Optional name. + * @options {any} options Data Source options + * @property {any} connector LoopBack connector. + * @property {*} [*] Other connector properties. + * See the relevant connector documentation + */ + + createDataSource(name: string, options: {connector: any, properties?: any}): void; + + /** + * Create a named vanilla JavaScript class constructor with an attached + * set of properties and options + * This function comes with two variants: + * * `loopback.createModel(name, properties, options)` + * * `loopback.createModel(config) + * In the second variant, the parameters `name`, `properties` and `options` + * are provided in the config object. Any additional config entries are + * interpreted as `options`, i.e. the following two configs are identical + * ```js + * { name: 'Customer', base: 'User' } + * { name: 'Customer', options: { base: 'User' } } + * `` + * **Example* + * Create an `Author` model using the three-parameter variant + * ```js + * loopback.createModel( + * 'Author', + * { + * firstName: 'string', + * lastName: 'string' + * }, + * { + * relations: { + * books: { + * model: 'Book', + * type: 'hasAndBelongsToMany' + * } + * } + * } + * ); + * `` + * Create the same model using a config object + * ```js + * loopback.createModel({ + * name: 'Author', + * properties: { + * firstName: 'string', + * lastName: 'string' + * }, + * relations: { + * books: { + * model: 'Book', + * type: 'hasAndBelongsToMany' + * } + * } + * }); + * `` + * @param {string} name Unique name. + * @param {any} properties + * @param {any} options (optional + * @header loopback.createMode + */ + + createModel(name: string, properties: any, options: any): void; + + /** + * Look up a model class by name from all models created by + * `loopback.createModel()` + * @param {string|() => void} modelOrName The model name or a `Model` constructor. + * @returns {Model} The model clas + * @header loopback.findModel(modelName + */ + + findModel(modelOrName: string ): Model; + + /** + * Look up a model class by name from all models created by + * `loopback.createModel()`. **Throw an error when no such model exists.* + * @param {string} modelOrName The model name or a `Model` constructor. + * @returns {Model} The model clas + * @header loopback.getModel(modelName + */ + + getModel(modelOrName: string): Model; + + /** + * Look up a model class by the base model class. + * The method can be used by LoopBack + * to find configured models in models.json over the base model. + * @param {Model} modelType The base model class + * @returns {Model} The subclass if found or the base clas + * @header loopback.getModelByType(modelType + */ + + getModelByType(modelType: Model): Model; + + /** + * Get an in-memory data source. Use one if it already exists + * @param {string} [name] The name of the data source. + * If not provided, the `'default'` is used + */ + + memory(name?: string): void; + + // **NOTE** DEPRECATE ON 3.x + // /** + // * Set the default `dataSource` for a given `type`. + // * @param {string} type The datasource type. + // * @param {any|DataSource} dataSource The data source settings or instance + // * @returns {DataSource} The data source instance. + // * + // * @header loopback.setDefaultDataSourceForType(type, dataSource) + // */ + + // setDefaultDataSourceForType(type: string, dataSource: any|DataSource): DataSource; + + // /** + // * Get the default `dataSource` for a given `type`. + // * @param {string} type The datasource type. + // * @returns {DataSource} The data source instance + // */ + + // getDefaultDataSourceForType(type: string): DataSource; + + // /** + // * Attach any model that does not have a dataSource to + // * the default dataSource for the type the Model requests + // */ + + // autoAttach(): void; + } + + /** + * Access context represents the context for a request to access protected + * resource + * @class + * @options {Context} context The context object + * @constructor + */ + + class AccessContext { + /** context The context object */ + constructor(context: Context); + + /** + * Add a principal to the context + * @param {string} principalType The principal type + * @param {*} principalId The principal id + * @param {string} [principalName] The principal name + * @returns {boolean} + */ + + addPrincipal(principalType: string, principalId: any, principalName?: string): boolean; + + /** + * Get the user id + * @returns {*} + */ + + getUserId(): any; + + /** + * Get the application id + * @returns {*} + */ + + getAppId(): any; + + /** + * Check if the access context has authenticated principals + * @returns {boolean} + */ + + isAuthenticated(): boolean; + } + + /** + * Context + * @interface + * @property {Principal[]} principals An Array of principals + * @property {() => void} model The model class + * @property {string} modelName The model name + * @property {string} modelId The model id + * @property {string} property The model property/method/relation name + * @property {string} method The model method to be invoked + * @property {string} accessType The access type + * @property {AccessToken} accessToken The access toke + * @returns {AccessContext} + */ + + interface Context { + /** An Array of principals */ + principals: Principal[]; + + /** The model class */ + model: () => void; + + /** The model name */ + modelName: string; + + /** The model id */ + modelId: string; + + /** The model property/method/relation name */ + property: string; + + /** The model method to be invoked */ + method: string; + + /** The access type */ + accesType: string; + + /** The access token */ + accessToken: AccessToken; + } + + /** + * A request to access protected resources. + * @param {string} model The model name + * @param {string} property + * @param {string} accessType The access type + * @param {string} permission The requested permission + * @returns {AccessRequest} + * @class + * @constructor + */ + + class AccessRequest { + constructor(model: string, property: string, accessType: string, permission: string); + + /** + * Does the given `ACL` apply to this `AccessRequest` + * @param {ACL} acl + */ + + exactlyMatches(acl: ACL): void; + + /** + * Is the request for access allowed + * @returns {boolean} + */ + + isAllowed(): boolean; + + /** + * Does the request contain any wildcards + * @returns {boolean} + */ + + isWildcard(): boolean; + } + + /** + * This class represents the abstract notion of a principal, which can be used + * to represent any entity, such as an individual, a corporation, and a login id + * @param {string} type The principal type + * @param {*} id The princiapl id + * @param {string} [name] The principal name + * @returns {Principal} + * @class + */ + + class Principal { + constructor(type: string, id: any, name: string); + + /** + * Compare if two principals are equal + * Returns true if argument principal is equal to this principal. + * @param {any} p The other principa + */ + + equals(p: any): void; + } + + /** + * The base class for **all models** + * **Inheriting from `Model`* + * ```js + * var properties = {...}; + * var options = {...}; + * var MyModel = loopback.Model.extend('MyModel', properties, options); + * `` + * **Options* + * - `trackChanges` - If true, changes to the model will be tracked. **Required + * for replication.* + * **Events* + * #### Event: `changed + * Emitted after a model has been successfully created, saved, or updated. + * Argument: `inst`, model instance, objec + * ```js + * MyModel.on('changed', function(inst) { + * console.log('model with id %s has been changed', inst.id); + * // => model with id 1 has been changed + * }); + * `` + * + * #### Event: `deleted + * Emitted after an individual model has been deleted. + * Argument: `id`, model ID (number) + * ```js + * MyModel.on('deleted', function(id) { + * console.log('model with id %s has been deleted', id); + * // => model with id 1 has been deleted + * }); + * `` + * #### Event: `deletedAll + * + * Emitted after an individual model has been deleted. + * Argument: `where` (optional), where filter, JSON object + * ```js + * MyModel.on('deletedAll', function(where) { + * if (where) { + * console.log('all models where ', where, ' have been deleted'); + * // => all models where + * // => {price: {gt: 100}} + * // => have been deleted + * } + * }); + * `` + * + * #### Event: `attached + * Emitted after a `Model` has been attached to an `app` + * #### Event: `dataSourceAttached + * Emitted after a `Model` has been attached to a `DataSource` + * #### Event: se + * Emitted when model property is set. + * Argument: `inst`, model instance, objec + * ```js + * MyModel.on('set', function(inst) { + * console.log('model with id %s has been changed', inst.id); + * // => model with id 1 has been changed + * }); + * `` + * + * @param {any} data + * @property {string} Model.modelName The name of the model. Static property. + * @property {DataSource} Model.dataSource Data source to which the model is connected, if any. Static property. + * @property {any} Model.sharedMethod The `strong-remoting` [SharedClass](apidocs.strongloop.com/strong-remoting/#sharedclass) that contains remoting (and http) metadata. Static property. + * @property {any} settings Contains additional model settings. + * @property {string} settings.http.path Base URL of the model HTTP route. + * @property [{string}] settings.acls Array of ACLs for the model. + * @class + * @constructor + */ + + class Model { + + /** The name of the model. */ + static modelName: string; + + /** Data source to which the model is connected, if any. */ + static dataSource: any; + + /** The `strong-remoting` */ + static sharedMethod: any; + + /** Contains additional model settings. */ + settings: Settings; + + constructor(data: any); + + /** + * Check if the given access token can invoke the specified method + * @param {AccessToken} token The access token. + * @param {*} modelId The model ID. + * @param {any} sharedMethod The method in question. + * @param {any} ctx The remote invocation context. + * @callback {() => void} callback The callback function. + * @param {string|Error} err The error object. + * @param {boolean} allowed True if the request is allowed; false otherwise + */ + + static checkAccess(token: AccessToken, modelId: any, sharedMethod: any, ctx: any, callback: (err: string|Error, allowed: boolean) => void): void; + + /** + * Disable remote invocation for the method with the given name + * @param {string} name The name of the method. + * @param {boolean} isStatic Is the method static (eg. `MyModel.myMethod`)? Pass + * `false` if the method defined on the prototype (eg. + * `MyModel.prototype.myMethod`) + */ + + static disableRemoteMethod(name: string, isStatic: boolean): void; + + /** + * Disable remote invocation for the method with the given name. + * @param {string} name The name of the method. + * The name of the method (include "prototype." if the method is defined on the prototype). + */ + + static disableRemoteMethodByName(name: string): void; + + /** + * Get the `Application` object to which the Model is attached + * @callback {() => void} callback Callback function called with `(err, app)` arguments. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {Application} app Attached application object. + * @end + */ + + static getApp(callback: (err: Error, app: Application) => void): void; + + /** + * Enabled deeply-nested queries of related models via REST API + * @param {string} relationName Name of the nested relation. + * @options {any} [options] It is optional. See below. + * @param {string} pathName The HTTP path (relative to the model) at which your remote method is exposed. + * @param {string} filterMethod The filter name. + * @param {string} paramName The argument name that the remote method accepts. + * @param {string} getterName The getter name. + * @param {boolean} hooks Whether to inherit before/after hooks. + * @callback {() => void} filterCallback The Optional filter function. + * @param {any} SharedMethod object. See [here](apidocs.strongloop.com/strong-remoting/#sharedmethod). + * @param {any} RelationDefinition object which includes relation `type`, `ModelConstructor` of `modelFrom`, `modelTo`, `keyFrom`, `keyTo` and more relation definitions + */ + + static nestRemoting(relationName: string, pathName: string, filterMethod: string, paramName: string, getterName: string, hooks: boolean, options?: {}, filterCallback?: (SharedMethod: any, RelationDefinition: any) => void): void; + + /** + * Enable remote invocation for the specified method. + * See [Remote methods](docs.strongloop.com/display/LB/Remote+methods) for more information + * Static method example: + * ```js + * Model.myMethod(); + * Model.remoteMethod('myMethod'); + * `` + * @param {string} name The name of the method. + * @param {any} options The remoting options. + * See [Remote methods - Options](docs.strongloop.com/display/LB/Remote+methods#Remotemethods-Options) + */ + + remoteMethod(name: string, options: any): void; + + /** + * The `loopback.Model.extend()` method calls this when you create a model that extends another model. + * Add any setup or configuration code you want executed when the model is created. + * See [Setting up a custom model](docs.strongloop.com/display/LB/Extending+built-in+models#Extendingbuilt-inmodels-Settingupacustommodel) + */ + + static setup(): void; + } + + /** + * SharedClass + * Create a new SharedClass with the given options. + * **NOTE** TODO : exported from another module type definition called strong-remoting + * + * @param {string} name The SharedClass name + * @param {() => void} constructor The constructor the SharedClass represents + * @param {any} options Additional options. + * @property {() => void } ctor The constructor + * @property {any} http The HTTP settings + */ + + class SharedClass { + /** The SharedClass name */ + ctor: () => void; + http: any; + + constructor(name: string, constructor: () => void); + + /** + * Normalize HTTP path. + */ + static normalizeHttpPath(): void; + + /** + * Define a shared method with the given name. + * @param {string} name The method name + * @param {any} options Set of options used to create a SharedMethod. See the full set of options https://apidocs.strongloop.com/strong-remoting/#sharedmethod + */ + + defineMethod(name: string, options: any): void; + + /** + * Disable a sharedMethod with the given name or function object. + * @param {string} fn The function or method name + * @param {boolean} isStatic Disable a static or prototype method + */ + + disableMethod(fn: string, isStatic: boolean): void; + + /** + * Disable a sharedMethod with the given static or prototype method name. + * @param {string} methodName The method name + */ + + disableMethodByName(methodName: string): void; + + /** + * Find a sharedMethod with the given name or function object. + * @param {string|() => void} fn The function or method name + * @param {boolean} isStatic Required if fn is a String. Only find a static method with the given name. + * @return {any} SharedMethod https://apidocs.strongloop.com/strong-remoting/#sharedmethod + */ + + find(fn: () => void|string, isStatic: boolean ): any; + + /** + * Find a sharedMethod with the given static or prototype method name. + * @param {string} methodName the method name Find a static or prototype method with the given name. + * @return {any} SharedMethod + */ + + findMethodByName(methodName: string): any; + + /** + * Get a key for the given method. + * @param {string} fn The function or method name + * @param {boolean} isStatic Disable a static or prototype method + */ + + getKeyFromMethodNameAndTarget(fn: string, isStatic: boolean): void; + + /** + * Get all shared methods belonging to this shared class. + * @param {any} options + * @return {any[]} An array of shared methods SharedMethod[] + */ + + methods(options: {includeDisabled: boolean}): any[]; + + /** + * Define a shared method resolver for dynamically defining methods. + * ``` + * // below is a simple example + * sharedClass.resolve(function(define) { + * define('myMethod', { + * accepts: {arg: 'str', type: 'string'}, + * returns: {arg: 'str', type: 'string'} + * errors: [ { code: 404, message: 'Not Found', responseModel: 'Error' } ] + * }, myMethod); + * }); + * function myMethod(str, cb) { + * cb(null, str); + * } + * ``` + * + * @param {() => void} resolver The resolver function. + */ + + resolve(resolver: () => void): void; + } + + interface Settings { + http: { + path: string; + }; + acls: ACL[]; + } + + /** + * Extends Model with basic query and CRUD support + * **Change Event* + * Listen for model changes using the `change` event + * ```js + * MyPersistedModel.on('changed', function(obj) + * console.log(obj) // => the changed model + * }); + * ``` + * @class PersistedModel + */ + + class PersistedModel { + + /** + * Apply an update list + * **Note: this is not atomic* + * @param {Array} updates An updates list, usually from [createUpdates()](#persistedmodel-createupdates). + * @param {any} options An optional options object to pass to underlying data-access calls. + * @param {() => void} callback Callback function + */ + + static bulkUpdate(updates: any[], options: any, callback: () => void): void; + + /** + * Get the changes to a model since the specified checkpoint. Provide a filter object + * to reduce the number of results returned. + * @param {number} since Return only changes since this checkpoint. + * @param {any} filter Include only changes that match this filter, the same as for [#persistedmodel-find](find()). + * @callback {() => void} callback Callback function called with `(err, changes)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {Array} changes An Array of [Change](#change) objects + */ + + static changes(since: number, filter: any, callback: (err: Error, changes: any[]) => void): void; + + /** + * Create a checkpoint + * @param {() => void} callback + */ + + static checkpoint(callback: () => void): void; + + /** + * Return the number of records that match the optional "where" filter. + * @param {any} [where] Optional where filter, like + * ``` + * { key: val, key2: {gt: 'val2'}, ...} + * ``` + *
See + * [Where filter](docs.strongloop.com/display/LB/Where+filter#Wherefilter-Whereclauseforothermethods). + * @callback {() => void} callback Callback function called with `(err, count)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {number} count number of instances updated + */ + + static count(where?: any, callback?: (err: Error, count: number) => void): void; + + /** + * Create new instance of Model, and save to database + * @param {any}|[{any}] data Optional data argument. Can be either a single model instance or an Array of instances + * @callback {() => void} callback Callback function called with `cb(err, obj)` signature. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} models Model instances or null + */ + + static create(data?: any|any[], callback?: (err: Error, models: any) => void): void; + + /** + * Create a change stream. See here for more info http://loopback.io/doc/en/lb2/Realtime-server-sent-events.html + * @param {any} options Only changes to models matching this where filter will be included in the ChangeStream. + * @param {() => void} callback + */ + + static createChangeStream(options: {where: any}, callback: (err: Error, changes: any) => void): void; + + /** + * Create an update list (for `Model.bulkUpdate()`) from a delta list + * (result of `Change.diff()`) + * @param {Array} deltas + * @param {() => void} callback + */ + + static createUpdates(deltas: any[], callback: () => void): void; + + /** + * Get the current checkpoint ID + * @callback {() => void} callback Callback function called with `(err, currentCheckpointId)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {number} currentCheckpointId Current checkpoint ID + */ + + static currentCheckpoint(callback: (err: Error, currentCheckpointId: number) => void): void; + + /** + * Destroy all model instances that match the optional `where` specification + * @param {any} [where] Optional where filter, like: + * ``` + * {key: val, key2: {gt: 'val2'}, ...} + * ``` + *
See + * [Where filter](docs.strongloop.com/display/LB/Where+filter#Wherefilter-Whereclauseforothermethods) + * + * @callback {() => void} callback Optional callback function called with `(err, info)` arguments. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} info Additional information about the command outcome. + * @param {number} info.count number of instances (rows, documents) destroyed + */ + + static destroyAll(where?: any, callback?: (err: Error, info: any, infoCount: number) => void): void; + + /** + * Destroy model instance with the specified ID. + * @param {*} id The ID value of model instance to delete. + * @callback {() => void} callback Callback function called with `(err)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object) + */ + + static destroyById(id: any, callback: (err: Error) => void): void; + + /** + * Get a set of deltas and conflicts since the given checkpoint + * See [Change.diff()](#change-diff) for details + * @param {number} since Find deltas since this checkpoint. + * @param {Array} remoteChanges An Array of change objects. + * @callback {() => void} callback Callback function called with `(err, result)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} result any with `deltas` and `conflicts` properties; see [Change.diff()](#change-diff) for details + */ + + static diff(since: number, remoteChanges: any[], callback: (err: Error, result: any) => void): void; + + /** + * Enable the tracking of changes made to the model. Usually for replication. + */ + + static enableChangeTracking(): void; + + /** + * Check whether a model instance exists in database + * @param {id} id Identifier of object (primary key value) + * @callback {() => void} callback Callback function called with `(err, exists)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {boolean} exists True if the instance with the specified ID exists; false otherwise + */ + + static exists(id: any, callback: (err: Error, exists: boolean) => void): void; + + /** + * Find all model instances that match `filter` specification. + * See [Querying models](docs.strongloop.com/display/LB/Querying+models) + * @options {any} [filter] Optional Filter JSON object; see below. + * @property {string|any|Array} fields Identify fields to include in return result. + *
See [Fields filter](docs.strongloop.com/display/LB/Fields+filter). + * @property {string|any|Array} include See PersistedModel.include documentation. + *
See [Include filter](docs.strongloop.com/display/LB/Include+filter). + * @property {number} limit Maximum number of instances to return. + *
See [Limit filter](docs.strongloop.com/display/LB/Limit+filter). + * @property {string} order Sort order: either "ASC" for ascending or "DESC" for descending. + *
See [Order filter](docs.strongloop.com/display/LB/Order+filter). + * @property {number} skip number of results to skip. + *
See [Skip filter](docs.strongloop.com/display/LB/Skip+filter). + * @property {any} where Where clause, like + * ``` + * { where: { key: val, key2: {gt: 'val2'}, ...} } + * ``` + *
See + * [Where filter](docs.strongloop.com/display/LB/Where+filter#Wherefilter-Whereclauseforqueries) + * @callback {() => void} callback Callback function called with `(err, returned-instances)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {Array} models Model instances matching the filter, or null if none found + */ + + static find(filter?: {fields?: string|any|any[]; include?: string|any|any[]; limit?: number; order?: string; skip?: number; where?: any; }, callback?: (err: Error, models: any[]) => void): void; + + /** + * Find object by ID with an optional filter for include/fields + * @param {*} id Primary key value + * @options {any} [filter] Optional Filter JSON object; see below. + * @property {string|any|Array} fields Identify fields to include in return result. + *
See [Fields filter](docs.strongloop.com/display/LB/Fields+filter). + * @property {string|any|Array} include See PersistedModel.include documentation. + *
See [Include filter](docs.strongloop.com/display/LB/Include+filter). + * @callback {() => void} callback Callback function called with `(err, instance)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Model instance matching the specified ID or null if no instance matches + */ + + static findById(id: any, filter?: {fields?: string|any|any[]; include?: string|any|any[]; }, callback?: (err: Error, instance: any) => void): void; + + /** + * Find one model instance that matches `filter` specification. + * Same as `find`, but limited to one result; + * Returns object, not collection + * @options {any} [filter] Optional Filter JSON object; see below. + * @property {string|any|Array} fields Identify fields to include in return result. + *
See [Fields filter](docs.strongloop.com/display/LB/Fields+filter). + * @property {string|any|Array} include See PersistedModel.include documentation. + *
See [Include filter](docs.strongloop.com/display/LB/Include+filter). + * @property {string} order Sort order: either "ASC" for ascending or "DESC" for descending. + *
See [Order filter](docs.strongloop.com/display/LB/Order+filter). + * @property {number} skip number of results to skip. + *
See [Skip filter](docs.strongloop.com/display/LB/Skip+filter). + * @property {any} where Where clause, like + * ``` + * {where: { key: val, key2: {gt: 'val2'}, ...} } + * ``` + *
See + * [Where filter](docs.strongloop.com/display/LB/Where+filter#Wherefilter-Whereclauseforqueries) + * @callback {() => void} callback Callback function called with `(err, returned-instance)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {Array} model First model instance that matches the filter or null if none found + */ + + static findOne(filter?: {fields: string|any|any[]; include: string|any|any[]; order: string; skip: number; where: any; }, callback?: (err: Error, model: any[]) => void): void; + + /** + * Finds one record matching the optional filter object. If not found, creates + * the object using the data provided as second argument. In this sense it is + * the same as `find`, but limited to one object. Returns an object, not + * collection. If you don't provide the filter object argument, it tries to + * locate an existing object that matches the `data` argument + * + * @options {any} [filter] Optional Filter object; see below. + * @property {string|any|Array} fields Identify fields to include in return result. + *
See [Fields filter](docs.strongloop.com/display/LB/Fields+filter). + * @property {string|any|Array} include See PersistedModel.include documentation. + *
See [Include filter](docs.strongloop.com/display/LB/Include+filter). + * @property {number} limit Maximum number of instances to return. + *
See [Limit filter](docs.strongloop.com/display/LB/Limit+filter). + * @property {string} order Sort order: either "ASC" for ascending or "DESC" for descending. + *
See [Order filter](docs.strongloop.com/display/LB/Order+filter). + * @property {number} skip number of results to skip. + *
See [Skip filter](docs.strongloop.com/display/LB/Skip+filter). + * @property {any} where Where clause, like + * ``` + * {where: {key: val, key2: {gt: val2}, ...}} + * ``` + *
See + * [Where filter](docs.strongloop.com/display/LB/Where+filter#Wherefilter-Whereclauseforqueries). + * @param {any} data Data to insert if object matching the `where` filter is not found. + * @callback {() => void} callback Callback function called with `cb(err, instance, created)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Model instance matching the `where` filter, if found. + * @param {boolean} created True if the instance matching the `where` filter was created + */ + + static findOrCreate(data: any, filter?: {fields?: string|any|any[]; include?: string|any|any[]; limit?: number; order?: string; skip?: number; where?: any; }, callback?: (err: Error, instance: any, created: boolean) => void): void; + + /** + * Get the `Change` model. + * Throws an error if the change model is not correctly setup. + */ + + static getChangeModel(): void; + + /** + * Get the `id` property name of the constructor + * @returns {string} The `id` property nam + */ + + static getIdName(): string; + + /** + * Get the source identifier for this model or dataSource + * @callback {() => void} callback Callback function called with `(err, id)` arguments. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {string} sourceId Source identifier for the model or dataSource + */ + + static getSourceId(callback: (err: Error, sourceId: string) => void): void; + + /** + * Handle a change error. Override this method in a subclassing model to customize + * change error handling + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object) + */ + + static handleChangeError(err: Error): void; + + /** + * Specify that a change to the model with the given ID has occurred + * @param {*} id The ID of the model that has changed. + * @callback {() => void} callback + * @param {Error} er + */ + + static rectifyChange(id: any, callback: (err: Error) => void): void; + + /** + * Replace attributes for a model instance whose id is the first input + * argument and persist it into the datasource. + * Performs validation before replacing + * @param {*} id The ID value of model instance to replace. + * @param {any} data Data to replace. + * @options {any} [options] Options for replace + * @property {boolean} validate Perform validation before saving. Default is true. + * @callback {() => void} callback Callback function called with `(err, instance)` arguments. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Replaced instance + */ + + static replaceById(id: any, data: any, options?: {validate: boolean; }, callback?: (err: Error, instance: any) => void): void; + + /** + * Replace or insert a model instance; replace existing record if one is found, + * such that parameter `data.id` matches `id` of model instance; otherwise, + * insert a new record. + * @param {any} data The model instance data. + * @options {any} [options] Options for replaceOrCreate + * @property {boolean} validate Perform validation before saving. Default is true. + * @callback {() => void} callback Callback function called with `cb(err, obj)` signature. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} model Replaced model instance. + */ + + static replaceOrCreate(data: any, options?: {validate: boolean; }, callback?: (err: Error, model: any) => void): void; + + /** + * Replicate changes since the given checkpoint to the given target model + * @param {number} [since] Since this checkpoint + * @param {Model} targetModel Target this model class + * @param {any} [options] + * @param {any} [options.filter] Replicate models that match this filter + * @callback {() => void} [callback] Callback function called with `(err, conflicts)` arguments. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {Conflict[]} conflicts A list of changes that could not be replicated due to conflicts. + * @param {any] checkpoints The new checkpoints to use as the "since" + * argument for the next replication + */ + + static replicate(since?: number, targetModel?: Model, options?: any, optionsFilter?: any, callback?: (err: Error, conflicts: Conflict[], param: any) => void): void; + + /** + * Update multiple instances that match the where clause. + * + * Example: + * + *```js + * Employee.updateAll({managerId: 'x001'}, {managerId: 'x002'}, function(err, info) { + * ... + * }); + * ``` + * + * @param {any} [where] Optional `where` filter, like + * ``` + * { key: val, key2: {gt: 'val2'}, ...} + * ``` + *
see + * [Where filter](docs.strongloop.com/display/LB/Where+filter#Wherefilter-Whereclauseforothermethods). + * @param {any} data any containing data to replace matching instances, if any. + * + * @callback {() => void} callback Callback function called with `(err, info)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} info Additional information about the command outcome. + * @param {number} info.count number of instances (rows, documents) updated. + * + */ + + static updateAll(where?: any, data?: any, callback?: (err: Error, info: any, infoCount: number) => void): void; + + /** + * Update or insert a model instance + * @param {any} data The model instance data to insert. + * @callback {() => void} callback Callback function called with `cb(err, obj)` signature. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} model Updated model instance + */ + + static upsert(data: any, callback: (err: Error, model: any) => void): void; + + /** + * Update or insert a model instance based on the search criteria. + * If there is a single instance retrieved, update the retrieved model. + * Creates a new model if no model instances were found. + * Returns an error if multiple instances are found. + * * @param {any} [where] `where` filter, like + * ``` + * { key: val, key2: {gt: 'val2'}, ...} + * ``` + *
see + * [Where filter](docs.strongloop.com/display/LB/Where+filter#Wherefilter-Whereclauseforothermethods). + * @param {any} data The model instance data to insert. + * @callback {() => void} callback Callback function called with `cb(err, obj)` signature. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} model Updated model instance + */ + + static upsertWithWhere(data: any, callback: (err: Error, model: any) => void): void; + + /** + * Deletes the model from persistence. + * Triggers `destroy` hook (async) before and after destroying object. + * @param {() => void} callback Callback function + */ + + destroy(callback: () => void): void; + + /** + * Get the `id` value for the `PersistedModel` + * @returns {*} The `id` valu + */ + + getId(): any; + + /** + * Get the `id` property name of the constructor + * @returns {string} The `id` property nam + */ + + getIdName(): string; + + /** + * Determine if the data model is new. + * @returns {boolean} Returns true if the data model is new; false otherwise + */ + + isNewRecord(): boolean; + + /** + * Reload object from persistence. Requires `id` member of `object` to be able to call `find`. + * @callback {() => void} callback Callback function called with `(err, instance)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Model instance + */ + + reload(callback: (err: Error, instance: any) => void): void; + + /** + * Replace attributes for a model instance and persist it into the datasource. + * Performs validation before replacing + * @param {any} data Data to replace. + * @options {any} [options] Options for replace + * @property {boolean} validate Perform validation before saving. Default is true. + * @callback {() => void} callback Callback function called with `(err, instance)` arguments. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Replaced instance + */ + + replaceAttributes(data: any, options?: {validate: boolean}, callback?: (err: Error, instance: any) => void): void; + + /** + * Save model instance. If the instance doesn't have an ID, then calls [create](#persistedmodelcreatedata-cb) instead. + * Triggers: validate, save, update, or create. + * @options {any} [options] See below. + * @property {boolean} validate Perform validation before saving. Default is true. + * @property {boolean} throws If true, throw a validation error; WARNING: This can crash Node. + * If false, report the error via callback. Default is false. + * @callback {() => void} callback Optional callback function called with `(err, obj)` arguments. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Model instance saved or created + */ + + save(options?: {validate: boolean; throws: boolean}, callback?: (err: Error, instance: any) => void): void; + + /** + * Set the correct `id` property for the `PersistedModel`. Uses the `setId` method if the model is attached to + * connector that defines it. Otherwise, uses the default lookup. + * Override this method to handle complex IDs + * @param {*} val The `id` value. Will be converted to the type that the `id` property specifies + */ + + setId(val: any): void; + + /** + * Update a single attribute. + * Equivalent to `updateAttributes({name: 'value'}, cb) + * @param {string} name Name of property. + * @param {any} value Value of property. + * @callback {() => void} callback Callback function called with `(err, instance)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Updated instance + */ + + updateAttribute(name: string, value: any, callback: (err: Error, instance: any) => void): void; + + /** + * Update set of attributes. Performs validation before updating + * Triggers: `validation`, `save` and `update` hooks + * @param {any} data Data to update. + * @callback {() => void} callback Callback function called with `(err, instance)` arguments. Required. + * @param {Error} err Error object; see [Error object](docs.strongloop.com/display/LB/Error+object). + * @param {any} instance Updated instance + */ + + updateAttributes(data: any, callback: (err: Error, instance: any) => void): void; + + // **NOTE** Deprecate for v3.x + // /** + // * Alias for `destroyAll` + // */ + + // **NOTE** Deprecate for v3.x + // deleteAll(): void; + + // **NOTE** Deprecate for v3.x + // /** + // * Alias for updateAll. + // */ + + // update(): void; + + // **NOTE** Deprecate for v3.x + // /** + // * Alias for destroyById. + // */ + + // removeById(): void; + + // **NOTE** Deprecate for v3.x + // /** + // * Alias for destroyById. + // */ + + // deleteById(): void; + + // **NOTE** Deprecate for v3.x + // /** + // * Alias for destroy. + // * @header PersistedModel.remove + // */ + + // remove(): void; + + // **NOTE** Deprecate for v3.x + // /** + // * Alias for destroy. + // * @header PersistedModel.delete + // */ + + // delete(): void; + + // **NOTE** Deprecate for v3.x + // /** + // * Create a change stream. [See here for more info](docs.strongloop.com/pages/viewpage.action?pageId=6721710) + // * + // * @param {any} options + // * @param {any} options.where Only changes to models matching this where filter will be included in the `any`. + // * @callback {() => void} callback + // * @param {Error} err + // * @param {any} changes + // */ + + // createany(options: any, optionsWhere: any, callback: (err: Error, changes: any) => void): void; + + } + + /** + * Serve the LoopBack favicon. + * @header loopback.favicon( + */ + + function favicon(): void; + + /** + * Expose models over REST + * For example: + * ```js + * app.use(loopback.rest()); + * ``` + * For more information, see [Exposing models over a REST API](docs.strongloop.com/display/DOC/Exposing+models+over+a+REST+API). + * @header loopback.rest( + */ + + function rest(): void; + + /** + * Serve static assets of a LoopBack application + * @param {string} root The root directory from which the static assets are to + * be served. + * @param {any} options Refer to + * [express documentation](expressjs.com/4x/api.html#express.static) + * for the full list of available options. + * @header loopback.static(root, [options]) + */ + + function static(root: string, options: any): void; + + /** + * Return HTTP response with basic application status information: + * date the application was started and uptime, in JSON format. For example: + * ``` + * { + * "started": "2014-06-05T00:26:49.750Z", + * "uptime": 9.394 + * } + * ``` + */ + + function status(): void; + + /** + * Rewrite the url to replace current user literal with the logged in user id + */ + + function rewriteUserLiteral(): void; + + /** + * Check for an access token in cookies, headers, and query string parameters. + * This function always checks for the following + * - `access_token` (params only) + * - `X-Access-Token` (headers only) + * - `authorization` (headers and cookies + * + * It checks for these values in cookies, headers, and query string parameters _in addition_ to the items + * specified in the options parameter + * **NOTE:** This function only checks for [signed cookies](expressjs.com/api.html#req.signedCookies) + * The following example illustrates how to check for an `accessToken` in a custom cookie, query string parameter + * and header called `foo-auth` + * ```js + * app.use(loopback.token({ + * cookies: ['foo-auth'], + * headers: ['foo-auth', 'X-Foo-Auth'], + * params: ['foo-auth', 'foo_auth'] + * })); + * ``` + * + * @options {any} [options] Each option Array is used to add additional keys to find an `accessToken` for a `request`. + * @property {Array} [cookies] Array of cookie names. + * @property {Array} [headers] Array of header names. + * @property {Array} [params] Array of param names. + * @property {boolean} [searchDefaultTokenKeys] Use the default search locations for Token in request + * @property {boolean} [enableDoublecheck] Execute middleware although an instance mounted earlier in the chain didn't find a token + * @property {boolean} [overwriteExistingToken] only has effect in combination with `enableDoublecheck`. If truthy, will allow to overwrite an existing accessToken. + * @property {() => void|string} [model] AccessToken model name or class to use. + * @property {string} [currentUserLiteral] string literal for the current user. + * @header loopback.token([options]) + */ + + function token(options?: {cookies?: any[], headers?: any[], params?: any[], searchDefaultTokenKeys?: boolean, enableDoublecheck?: boolean, overwriteExistingToken?: boolean, model?: () => void|string, currentUserLiteral?: string}): void; + + /** + * Convert any request not handled so far to a 404 error + * to be handled by error-handling middleware. + * @header loopback.urlNotFound( + */ + + function urlNotFound(): void; + + /** + * Token based authentication and access control + * **Default ACLs* + * - DENY EVERYONE `*` + * - ALLOW EVERYONE creat + * @property {string} id Generated token ID. + * @property {number} ttl Time to live in seconds, 2 weeks by default. + * @property {Date} created When the token was created. + * @property {any} settings Extends the `Model.settings` object. + * @property {number} settings.accessTokenIdLength Length of the base64-encoded string access token. Default value is 64. + * Increase the length for a more secure access token + * @class AccessToken + * @inherits {PersistedModel} + */ + + class AccessToken extends PersistedModel { + + /** Generated token ID */ + id: string; + + /** Time to live in seconds, 2 weeks by default. */ + ttl: number; + + /** When the token was created. */ + created: Date; + + /** Extends the `Model.settings` object. */ + settings: { http: { path: string }; acls: ACL, accessTokenIdLength: number}; + + /** + * Create a cryptographically random access token id + * @callback {() => void} callback + * @param {Error} err + * @param {string} toke + */ + + static createAccessTokenId(callback: (err: Error, token: string) => void): void; + + /** + * Find a token for the given `any` + * @param {any} req + * @param {any} [options] Options for finding the token + * @callback {() => void} callback + * @param {Error} err + * @param {AccessToken} toke + */ + + static findForRequest(req: any, options?: any, callback?: (err: Error, token: AccessToken) => void): void; + + /** + * Validate the token. + * + * @callback {() => void} callback + * @param {Error} err + * @param {boolean} isValid + */ + + validate(callback: (err: Error, isValid: boolean) => void): void; + + // **NOTE** Deprecate for 3.x + // /** + // * Anonymous Token + // * + // * ```js + // * assert(AccessToken.ANONYMOUS.id === '$anonymous'); + // * ``` + // */ + + // ANONYMOUS(): void; + + } + + /** + * A Model for access control meta data + * System grants permissions to principals (users/applications, can be grouped + * into roles) + * Protected resource: the model data and operations + * (model/property/method/relation/… + * For a given principal, such as client application and/or user, is it allowed + * to access (read/write/execute) + * the protected resource + * @header ACL + * @property {string} model Name of the model. + * @property {string} property Name of the property, method, scope, or relation. + * @property {string} accessType Type of access being granted: one of READ, WRITE, or EXECUTE. + * @property {string} permission Type of permission granted. One of + * - ALARM: Generate an alarm, in a system-dependent way, the access specified in the permissions component of the ACL entry. + * - ALLOW: Explicitly grants access to the resource. + * - AUDIT: Log, in a system-dependent way, the access specified in the permissions component of the ACL entry. + * - DENY: Explicitly denies access to the resource. + * @property {string} principalType Type of the principal; one of: Application, Use, Role. + * @property {string} principalId ID of the principal - such as appId, userId or roleId. + * @property {any} settings Extends the `Model.settings` object. + * @property {string} settings.defaultPermission Default permission setting: ALLOW, DENY, ALARM, or AUDIT. Default is ALLOW. + * Set to DENY to prohibit all API access by default + * @class ACL + * @inherits PersistedMode + */ + + class ACL extends PersistedModel { + /** model Name of the model. */ + model: string; + + /** property Name of the property, method, scope, or relation. */ + property: string; + + /** accessType Type of access being granted: one of READ, WRITE, or EXECUTE. */ + accesType: 'READ' | 'WRITE' | 'EXECUTE'; + + /**permission Type of permission granted One of: + * - ALARM: Generate an alarm, in a system-dependent way, the access specified in the permissions component of the ACL entry. + * - ALLOW: Explicitly grants access to the resource. + * - AUDIT: Log, in a system-dependent way, the access specified in the permissions component of the ACL entry. + * - DENY: Explicitly denies access to the resource. + */ + permission: 'ALARM' | 'ALLOW' | 'AUDIT' | 'DENY'; + + /** principalType Type of the principal; one of: Application, Use, Role. */ + principalType: 'Aplication' | 'User' | 'Role' | string; + + /** principalId ID of the principal - such as appId, userId or roleId. */ + principalId: string; + + /** settings Extends the `Model.settings` object. */ + settings: { http: { path: string }; acls: ACL, defaultPermission: 'DENY'}; + + /** + * Check if the request has the permission to access. + * @options {any} context See below. + * @property {any[]} principals An Array of principals. + * @property {string|Model} model The model name or model class. + * @property {*} id The model instance ID. + * @property {string} property The property/method/relation name. + * @property {string} accessType The access type: + * READ, REPLICATE, WRITE, or EXECUTE. + * @param {() => void} callback Callback functio + */ + + static checkAccessForContext(context: {principals: any[]; model: string|Model; id: any; property: string; accessType: string; }, callback: () => void): void; + + /** + * Check if the given access token can invoke the method + * @param {AccessToken} token The access token + * @param {string} model The model name + * @param {*} modelId The model id + * @param {string} method The method name + * @callback {() => void} callback Callback function + * @param {string|Error} err The error object + * @param {boolean} allowed is the request allow + */ + + static checkAccessForToken(token: AccessToken, model: string, modelId: any, method: string, callback: (err: string|Error, allowed: boolean) => void): void; + + /** + * Check if the given principal is allowed to access the model/property + * @param {string} principalType The principal type. + * @param {string} principalId The principal ID. + * @param {string} model The model name. + * @param {string} property The property/method/relation name. + * @param {string} accessType The access type. + * @callback {() => void} callback Callback function. + * @param {string|Error} err The error object + * @param {AccessRequest} result The access permissio + */ + + static checkPermission(principalType: string, principalId: string, model: string, property: string, accessType: string, callback: (err: string|Error, result: AccessRequest) => void): void; + + /** + * Calculate the matching score for the given rule and request + * @param {ACL} rule The ACL entry + * @param {AccessRequest} req The request + * @returns {number} + */ + + static getMatchingScore(rule: ACL, req: AccessRequest): number; + + /** + * Check if the given principal is mapped to the role + * @param {string} principalType Principal type + * @param {string|*} principalId Principal id/name + * @param {string|*} role Role id/name + * @param {() => void} cb Callback functio + */ + + static isMappedToRole(principalType: string, principalId: string|any, role: string|any, cb: () => void): void; + + /** + * Resolve a principal by type/id + * @param {string} type Principal type - ROLE/APP/USER + * @param {string|number} id Principal id or name + * @param {() => void} cb Callback function + */ + + static resolvePrincipal(type: string, id: string|number, cb: () => void): void; + + /** + * Get matching score for the given `AccessRequest`. + * @param {AccessRequest} req The request + * @returns {number} scor + */ + + score(req: AccessRequest): number; + } + + /** + * Manage client applications and organize their users + * @property {string} id Generated ID. + * @property {string} name Name; required. + * @property {string} description Text description + * @property {string} icon string Icon image URL. + * @property {string} owner User ID of the developer who registers the application. + * @property {string} email E-mail address + * @property {boolean} emailVerified Whether the e-mail is verified. + * @property {string} url OAuth 2.0 application URL. + * @property {string}[]} callbackUrls The OAuth 2.0 code/token callback URL. + * @property {string} status Status of the application; Either `production`, `sandbox` (default), or `disabled`. + * @property {Date} created Date Application object was created. Default: current date. + * @property {Date} modified Date Application object was modified. Default: current date + * @property {any} pushSettings.apns APNS configuration, see the options + * below and also + * github.com/argon/node-apn/blob/master/doc/apn.markdown + * @property {boolean} pushSettings.apns.production Whether to use production Apple Push Notification Service (APNS) servers to send push notifications. + * If true, uses `gateway.push.apple.com:2195` and `feedback.push.apple.com:2196`. + * If false, uses `gateway.sandbox.push.apple.com:2195` and `feedback.sandbox.push.apple.com:2196` + * @property {string} pushSettings.apns.certData The certificate data loaded from the cert.pem file (APNS). + * @property {string} pushSettings.apns.keyData The key data loaded from the key.pem file (APNS). + * @property {string} pushSettings.apns.pushOptions.gateway (APNS). + * @property {number} pushSettings.apns.pushOptions.port (APNS). + * @property {string} pushSettings.apns.feedbackOptions.gateway (APNS). + * @property {number} pushSettings.apns.feedbackOptions.port (APNS). + * @property {boolean} pushSettings.apns.feedbackOptions.batchFeedback (APNS). + * @property {number} pushSettings.apns.feedbackOptions.interval (APNS). + * @property {string} pushSettings.gcm.serverApiKey: Google Cloud Messaging API key + * @property {boolean} authenticationEnabled + * @property {boolean} anonymousAllowed + * @property {Array} authenticationSchemes List of authentication schemes + * (see below). + * @property {string} authenticationSchemes.scheme Scheme name. + * Supported values: `local`, `facebook`, `google`, + * `twitter`, `linkedin`, `github`. + * @property {any} authenticationSchemes.credential + * Scheme-specific credentials + * @class Application + * @inherits {PersistedModel} + */ + + class Application extends PersistedModel { + /** Generated ID. */ + id: string; + + /** Name; required. */ + name: string; + + /** Text description */ + description: string; + + /** string Icon image URL. */ + icon: string; + + /** User ID of the developer who registers the application. */ + owner: string; + + /** E-mail address */ + email: string; + + /** Whether the e-mail is verified. */ + emailVerified: string; + + /** OAuth 2.0 application URL. */ + url: string; + + /** The OAuth 2.0 code/token callback URL. */ + callBackUrl: string[]; + + /** Status of the application; Either `production`, `sandbox` (default), or `disabled`. */ + status: string; + + /** Date Application object was created. Default: current date. */ + created: Date; + + /** modified Date Application object was modified. Default: current date. */ + modified: Date; + + /** + * pushSettings.apns APNS configuration, see the options + * below and also + * github.com/argon/node-apn/blob/master/doc/apn.markdown + * pushSettings.apns.production Whether to use production Apple Push Notification Service (APNS) servers to send push notifications. + * If true, uses `gateway.push.apple.com:2195` and `feedback.push.apple.com:2196`. + * If false, uses `gateway.sandbox.push.apple.com:2195` and `feedback.sandbox.push.apple.com:2196` + * pushSettings.apns.certData The certificate data loaded from the cert.pem file (APNS). + * pushSettings.apns.keyData The key data loaded from the key.pem file (APNS). + * pushSettings.apns.pushOptions.gateway (APNS). + * pushSettings.apns.pushOptions.port (APNS). + * pushSettings.apns.feedbackOptions.gateway (APNS). + * pushSettings.apns.feedbackOptions.port (APNS). + * pushSettings.apns.feedbackOptions.batchFeedback (APNS). + * pushSettings.apns.feedbackOptions.interval (APNS). + * pushSettings.gcm.serverApiKey: Google Cloud Messaging API key. + */ + pushSetings: { + apns: { + production: boolean; + cerData: string; + keyData: string; + pushOptions: { + gateway: string; + port: number; + }; + feedBackOptions: { + gateway: string; + port: number; + batchFeedback: boolean; + interval: number; + }; + }; + gcm: { + serverApiKey: string; + } + }; + authenticationEnabled: boolean; + anonymousAllowed: boolean; + authenticationSchemes: string[]; + + /** + * Authenticate the application id and key + * @param {Any} appId + * @param {string} key + * @callback {() => void} callback + * @param {Error} err + * @param {string} matched The matching key; one of: + * - clientKey + * - javaScriptKey + * - restApiKey + * - windowsKey + * - masterKe + */ + + static authenticate(appId: any, key: string, callback: (err: Error, matched: string) => void): void; + + /** + * Register a new application + * @param {string} owner Owner's user ID. + * @param {string} name Name of the application + * @param {any} options Other options + * @param {() => void} callback Callback function + */ + + static register(owner: string, name: string, options: any, callback: () => void): void; + + /** + * Reset keys for the application instance + * @callback {() => void} callback + * @param {Error} err + */ + + static resetKeys(callback: (err: Error) => void): void; + + /** + * Reset keys for a given application by the appId + * @param {Any} appId + * @callback {() => void} callback + * @param {Error} err + */ + + resetKeys(appId: any, callback: (err: Error) => void): void; + } + + /** + * Change list entry. + * + * @property {string} id Hash of the modelName and ID. + * @property {string} rev The current model revision. + * @property {string} prev The previous model revision. + * @property {number} checkpoint The current checkpoint at time of the change. + * @property {string} modelName Model name. + * @property {string} modelId Model ID. + * @property {any} settings Extends the `Model.settings` object. + * @property {string} settings.hashAlgorithm Algorithm used to create cryptographic hash, used as argument + * to [crypto.createHash](nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm). Default is sha1. + * @property {boolean} settings.ignoreErrors By default, when changes are rectified, an error will throw an exception. + * However, if this setting is true, then errors will not throw exceptions. + * @class Change + * @inherits {PersistedModel} + */ + + class Change extends PersistedModel { + /** Hash of the modelName and ID. */ + id: string; + + /** The current model revision. */ + rev: string; + + + prev: string; + + checkpoint: number; + + /** Model name. */ + modelName: string; + + /** Model ID. */ + modelId: string; + + /** + * settings Extends the `Model.settings` object. + * settings.hashAlgorithm Algorithm used to create cryptographic hash, used as argument + * to [crypto.createHash](nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm).Default is sha1. + * settings.ignoreErrors By default, when changes are rectified, an error will throw an exception. + * However, if this setting is true, then errors will not throw exceptions. + */ + settings: { http: { path: string }; acls: ACL; hashAlgorithm: string; ignoreErrors: boolean; }; + + /** + * Are both changes deletes? + * @param {Change} a + * @param {Change} b + */ + + static bothDeleted(a: Change, b: Change): void; + + /** + * Determine the differences for a given model since a given checkpoint. + * + * The callback will contain an error or `result`. + * + * **result** + * + * ```js + * { + * deltas: Array, + * conflicts: Array + * } + * ``` + * + * **deltas** + * + * An Array of changes that differ from `remoteChanges`. + * + * **conflicts** + * + * An Array of changes that conflict with `remoteChanges`. + * + * @param {string} modelName + * @param {number} since Compare changes after this checkpoint + * @param {Change[]} remoteChanges A set of changes to compare + * @callback {() => void} callback + * @param {Error} err + * @param {any} result See above. + */ + + // static diff(modelName: string, since: number, remoteChanges: Change[], callback: (err: Error, result: any) => void): void; + + /** + * Find or create a change for the given model + * @param {string} modelName + * @param {string} modelId + * @callback {() => void} callback + * @param {Error} err + * @param {Change} change + * @end + */ + + static findOrCreateChange(modelName: string, modelId: string, callback: (err: Error, change: Change) => void): void; + + /** + * Get the checkpoint model. + */ + + static getCheckpointModel(): void; + + /** + * Create a hash of the given `string` with the `options.hashAlgorithm`. + * **Default: `sha1`* + * @param {string} str The string to be hashed + */ + + static hash(str: string): void; + + /** + * Get an identifier for a given model + * @param {string} modelName + * @param {string} modelId + */ + + static idForModel(modelName: string, modelId: string): void; + + /** + * Correct all change list entries. + * @param {() => void} c + */ + + static rectifyAll(cb: () => void): void; + + /** + * Track the recent change of the given modelIds + * @param {string} modelName + * @param {Array} modelIds + * @callback {() => void} callback + * @param {Error} err + * @param {Array} changes Changes that were tracke + */ + + static rectifyModelChanges(modelName: string, modelIds: any[], callback: (err: Error, changes: any[]) => void): void; + + /** + * Get the revision string for the given object + * @param {any} inst The data to get the revision string for + */ + + static revisionForInst(inst: any): void; + + /** + * Does this change conflict with the given change. + * @param {Change} change + * @return {boolean + */ + + conflictsWith(change: Change): void; + + /** + * Get a change's current revision based on current data. + * @callback {() => void} callback + * @param {Error} err + * @param {string} rev The current revisio + */ + + currentRevision(callback: (err: Error, rev: string) => void): void; + + /** + * Compare two changes. + * @param {Change} change + */ + + equals(change: Change): void; + + /** + * Get the `Model` class for `change.modelName`. + */ + + getModelCtor(): void; + + /** + * Determine if the change is based on the given change. + * @param {Change} change + * @return {boolean + */ + + isBasedOn(change: Change): void; + + /** + * Update (or create) the change with the current revision + * @callback {() => void} callback + * @param {Error} err + * @param {Change} chang + */ + + rectify(callback: (err: Error, change: Change) => void): void; + + /** + * Get a change's type. Returns one of + * - `Change.UPDATE` + * - `Change.CREATE` + * - `Change.DELETE` + * - `Change.UNKNOWN + */ + + type(): void; + } + + /** + * When two changes conflict a conflict is created + * **Note**: call `conflict.fetch()` to get the `target` and `source` models + * + * @param {*} modelId + * @param {PersistedModel} SourceModel + * @param {PersistedModel} TargetModel + * @property {ModelClass} source The source model instance + * @property {ModelClass} target The target model instance + * @class Change.Conflic + */ + + class Conflict { + source: any; + target: any; + constructor(modelId: any, SourceModel: PersistedModel, TargetModel: PersistedModel); + + /** + * Get the conflicting changes + * @callback {() => void} callback + * @param {Error} err + * @param {Change} sourceChange + * @param {Change} targetChang + */ + + changes(callback: (err: Error, sourceChange: Change, targetChange: Change) => void): void; + + /** + * Fetch the conflicting models + * @callback {() => void} callback + * @param {Error} err + * @param {PersistedModel} source + * @param {PersistedModel} targe + */ + + models(callback: (err: Error, source: PersistedModel, target: PersistedModel) => void): void; + + /** + * Resolve the conflict + * Set the source change's previous revision to the current revision of the + * (conflicting) target change. Since the changes are no longer conflicting + * and appear as if the source change was based on the target, they will be + * replicated normally as part of the next replicate() call + * This is effectively resolving the conflict using the source version + * @callback {() => void} callback + * @param {Error} err + */ + + resolve(callback: (err: Error) => void): void; + + /** + * Resolve the conflict using the supplied instance data + * @param {any} data The set of changes to apply on the model + * instance. Use `null` value to delete the source instance instead. + * @callback {() => void} callback + * @param {Error} err + */ + + resolveManually(data: any, callback: (err: Error) => void): void; + + /** + * Resolve the conflict using the instance data in the source model + * @callback {() => void} callback + * @param {Error} err + */ + + resolveUsingSource(callback: (err: Error) => void): void; + + /** + * Resolve the conflict using the instance data in the target model + * @callback {() => void} callback + * @param {Error} err + */ + + resolveUsingTarget(callback: (err: Error) => void): void; + + /** + * Return a new Conflict instance with swapped Source and Target models + * This is useful when resolving a conflict in one-way + * replication, where the source data must not be changed + * + * ```js + * conflict.swapParties().resolveUsingTarget(cb); + * ``` + * @returns {Conflict} A new Conflict instance + */ + + swapParties(): Conflict; + + /** + * Determine the conflict type + * Possible results ar + * + * - `Change.UPDATE`: Source and target models were updated + * - `Change.DELETE`: Source and or target model was deleted. + * - `Change.UNKNOWN`: the conflict type is uknown or due to an erro + * + * @callback {() => void} callback + * @param {Error} err + * @param {string} type The conflict type + */ + + type(callback: (err: Error, type: string) => void): void; + } + + /** + * Email model. Extends LoopBack base [Model](#model-new-model). + * @property {string} to Email addressee. Required. + * @property {string} from Email sender address. Required. + * @property {string} subject Email subject string. Required. + * @property {string} text Text body of email. + * @property {string} html HTML body of email + * @class Email + * @inherits {Model} + */ + + class Email extends Model { + /** Email addressee. Required. */ + to: string; + + /** Email sender address. Required. */ + from: string; + + /** Email subject string. Required. */ + subject: string; + + /** Text body of email. */ + text: string; + + /** HTML body of email. */ + html: string; + + /** + * Send an email with the given `options` + * Example Options + * ```js + * { + * from: "Fred Foo ", // sender address + * to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers + * subject: "Hello", // Subject line + * text: "Hello world", // plaintext body + * html: "Hello world" // html body + * } + * `` + * See github.com/andris9/Nodemailer for other supported options + * + * @options {any} options See below + * @prop {string} from Senders's email address + * @prop {string} to List of one or more recipient email addresses (comma-delimited) + * @prop {string} subject Subject line + * @prop {string} text Body text + * @prop {string} html Body HTML (optional) + * @param {() => void} callback Called after the e-mail is sent or the sending faile + */ + + static send(callback: () => void, options: { from: string; to: string; subject: string; text: string; html: string; }): void; + + /** + * A shortcut for Email.send(this). + */ + + send(): void; + + } + + /** + * Data model for key-value databases. + * @class + */ + class KeyValueModel { + + /** + * Set the TTL (time to live) in ms (milliseconds) for a given key. + * TTL is the remaining time before a key-value pair is discarded from the database. + * + * Callback (Optional) Optional callback. + * When the callback function is not provided, a promise is returned instead (see below). + * + * Promise + * this method supports both callback-based and promise-based invocation. + * Call this method with no callback argument to get back a promise instead. + * @param {string} key Key to use when searching the database. + * @param {number} ttl TTL in ms to set for the key. + * @param {any} options + * @param {() => void} callback + */ + + static expire(key: string, ttl: number, options: any, callback: () => void): PromiseLike; + + /** + * Return the value associated with a given key. + * + * Callback (Optional) + * Optional callback. When the callback function is not provided, a promise is returned instead (see below). + * + * Promise + * This method supports both callback-based and promise-based invocation. + * Call this method with no callback argument to get back a promise instead. + * + * @param {string} key Key to use when searching the database. + * @param {any} options + * @param {() => void} callback + */ + + static get(key: string, option?: any, callback?: (err: Error, result: any) => void): PromiseLike; + + /** + * Asynchronously iterate all keys in the database. Similar to .keys() + * but instead allows for iteration over large data sets without having + * to load everything into memory at once. + * Callback example: + * ``` + * // Given a model named `Color` with two keys `red` and `blue` + * var iterator = Color.iterateKeys(); + * t.next(function(err, key) { + * // key contains `red` + * it.next(function(err, key) { + * // key contains `blue` + * }); + * }); + * ``` + * + * Promise example: + * ``` + * // Given a model named `Color` with two keys `red` and `blue` + * var iterator = Color.iterateKeys(); + * Promise.resolve().then(function() { + * return it.next(); + * }) + * .then(function(key) { + * // key contains `red` + * return it.next(); + * }); + * .then(function(key) { + * // key contains `blue` + * }); + * ``` + * + * @param {any} filter An optional filter object with the following + * @param {string} filter.match Glob string to use to filter returned keys (i.e. userid.*). + * All connectors are required to support * and ?. + * They may also support additional special characters that are specific to the backing database. + * @param {any} filter.options + * @return {any} result AsyncIterator An Object implementing next(cb) -> Promise function that can be used to iterate all keys. + */ + + static iterateKeys(filter: {match: string; options: any}): any; + + /** + * Return all keys in the database. + * WARNING: This method is not suitable for large data sets as all key-values pairs + * are loaded into memory at once. For large data sets, use iterateKeys() instead. + * + * This method supports both callback-based and promise-based invocation. + * Call this method with no callback argument to get back a promise instead + * + * WARNING: this promise implementation will not resolve according to the callback function. + * + * @param {any} filter An optional filter object with the following + * @param {string} filter.match Glob string used to filter returned keys (i.e. userid.*). + * All connectors are required to support * and ?, but may also support additional special + * characters specific to the database. + * @param {any} filter.options + * @param {() => void} callback + * @return {PromiseLike} + */ + + static keys(filter: {match: string; options: any}, callback: () => void): PromiseLike; + + /** + * Persist a value and associate it with the given key. + * + * Callback (Optional) + * Optional callback. When the callback function is not provided, a promise is returned instead (see below). + * + * Promise + * This method supports both callback-based and promise-based invocation. + * Call this method with no callback argument to get back a promise instead. + * + * @param {string} key Key to associate with the given value. + * @param {any} value Value to persist. + * @param {number|any} Optional settings for the key-value pair. If a Number is provided, it is set as the TTL (time to live) in ms (milliseconds) for the key-value pair. + * @param {() => void} callback + */ + + static set(key: string, value: any, options?: number|any, callback?: (err: Error) => void): PromiseLike; + + /** + * Return the TTL (time to live) for a given key. + * TTL is the remaining time before a key-value pair is discarded from the database. + * + * Callback (Optional) + * Optional callback. When the callback function is not provided, + * a promise is returned instead (see below). + * + * @param {string} key Key to use when searching the database. + * @param {any} options + * @param {() => void} callback + */ + + static ttl(key: string, options?: any, cb?: (error: Error) => void): PromiseLike; + } + + /** + * The Role model + * @class Role + * @header Role objec + */ + + class Role { + /** + * List roles for a given principal. + * @param {any} context The security context. + * @callback {() => void} callback Callback function. + * @param {Error} err Error object. + * @param {string[]} roles An Array of role IDs + */ + + static getRoles(context: any, callback: (err: Error, roles: string[]) => void): void; + + /** + * Check if the user ID is authenticated + * @param {any} context The security context.@callback {() => void} callback Callback function. + * @param {Error} err Error object. + * @param {boolean} isAuthenticated True if the user is authenticated. + */ + + static isAuthenticated(context: any, callback: (err: Error, isAuthenticated: boolean) => void): void; + + /** + * Check if a given principal is in the specified role. + * @param {string} role The role name. + * @param {any} context The context object. + * @callback {() => void} callback Callback function. + * @param {Error} err Error object. + * @param {boolean} isInRole True if the principal is in the specified role. + */ + + static isInRole(role: string, context: any, callback: (err: Error, isInRole: boolean) => void): void; + + /** + * Check if a given user ID is the owner the model instance. + * @param {() => void} modelClass The model class + * @param {*} modelId The model ID + * @param {*} userId The user ID + * @param {() => void} callback Callback function + */ + + static isOwner(modelClass: () => void, modelId: any, userId: any, callback: () => void): void; + + /** + * Add custom handler for roles. + * @param {string} role Name of role. + * @param {() => void} resolver () => void that determines + * if a principal is in the specified role. + * Should provide a callback or return a promise. + */ + + static registerResolver(role: string, resolver: () => void): void; + } + + /** + * The `RoleMapping` model extends from the built in `loopback.Model` type. + * @property {string} id Generated ID. + * @property {string} name Name of the role. + * @property {string} Description Text description. + * @class RoleMapping + * @inherits {PersistedModel} + */ + + class RoleMapping extends PersistedModel { + + /** Generated ID. */ + id: string; + + /** Name of the role. */ + name: string; + + /** Description Text description. */ + description: string; + + /** + * Get the application principal + * @callback {() => void} callback + * @param {Error} err + * @param {Application} application + */ + + application(callback: (err: Error, application: Application) => void): void; + + /** + * Get the child role principal + * @callback {() => void} callback + * @param {Error} err + * @param {User} childUser + */ + + childRole(callback: (err: Error, childUser: User) => void): void; + + /** + * Get the user principal + * @callback {() => void} callback + * @param {Error} err + * @param {User} user + */ + + user(callback: (err: Error, user: User) => void): void; + } + + /** + * Resource owner grants/delegates permissions to client application + * For a protected resource, does the client application have the authorization + * from the resource owner (user or system) + * Scope has many resource access entrie + * @class scope + */ + + class Scope { + + /** + * Check if the given scope is allowed to access the model/property + * @param {string} scope The scope name + * @param {string} model The model name + * @param {string} property The property/method/relation name + * @param {string} accessType The access type + * @callback {() => void} callback + * @param {string|Error} err The error object + * @param {AccessRequest} result The access permission + */ + + static checkPermission(scope: string, model: string, property: string, accessType: string, callback: (err: string|Error, result: AccessRequest) => void): void; + + } + + /** + * Built-in User model. + * Extends LoopBack [PersistedModel](#persistedmodel-new-persistedmodel) + * Default `User` ACLs + * - DENY EVERYONE `*` + * - ALLOW EVERYONE `create` + * - ALLOW OWNER `deleteById` + * - ALLOW EVERYONE `login` + * - ALLOW EVERYONE `logout` + * - ALLOW OWNER `findById` + * - ALLOW OWNER `updateAttributes` + * + * @property {string} username Must be unique. + * @property {string} password Hidden from remote clients. + * @property {string} email Must be valid email. + * @property {boolean} emailVerified Set when a user's email has been verified via `confirm()`. + * @property {string} verificationToken Set when `verify()` is called. + * @property {string} realm The namespace the user belongs to. See [Partitioning users with realms](docs.strongloop.com/display/public/LB/Partitioning+users+with+realms) for details. + * @property {Date} created The property is not used by LoopBack, you are free to use it for your own purposes. + * @property {Date} lastUpdated The property is not used by LoopBack, you are free to use it for your own purposes. + * @property {string} status The property is not used by LoopBack, you are free to use it for your own purposes. + * @property {any} settings Extends the `Model.settings` object. + * @property {boolean} settings.emailVerificationRequired Require the email verification + * process before allowing a login. + * @property {number} settings.ttl Default time to live (in seconds) for the `AccessToken` created by `User.login() / user.createAccessToken()`. + * Default is `1209600` (2 weeks) + * @property {number} settings.maxTTL The max value a user can request a token to be alive / valid for. + * Default is `31556926` (1 year) + * @property {boolean} settings.realmRequired Require a realm when logging in a user. + * @property {string} settings.realmDelimiter When set a realm is required. + * @property {number} settings.resetPasswordTokenTTL Time to live for password reset `AccessToken`. Default is `900` (15 minutes). + * @property {number} settings.saltWorkFactor The `bcrypt` salt work factor. Default is `10`. + * @property {boolean} settings.caseSensitiveEmail Enable case sensitive email. + * + * @class User + * @inherits {PersistedModel} + */ + + class User extends PersistedModel { + + /** Must be unique. */ + username: string; + + /** Hidden from remote clients. */ + password: string; + /** Must be valid email. */ + email: string; + + /** Set when a user's email has been verified via `confirm()`. */ + emailVerified: boolean; + + /** Set when `verify()` is called. */ + verificationToken: string; + + /** The namespace the user belongs to. See [Partitioning users with realms](docs.strongloop.com/display/public/LB/Partitioning+users+with+realms) for details. */ + realm: string; + + /** The property is not used by LoopBack, you are free to use it for your own purposes. */ + created: Date; + + /** The property is not used by LoopBack, you are free to use it for your own purposes. */ + lastUpdate: Date; + + /** The property is not used by LoopBack, you are free to use it for your own purposes. */ + status: string; + + /** + * ettings Extends the `Model.settings` object. + * settings.emailVerificationRequired Require the email verification + * process before allowing a login. + * settings.ttl Default time to live (in seconds) for the `AccessToken` created by `User.login() / user.createAccessToken()`. + * Default is `1209600` (2 weeks) + * settings.maxTTL The max value a user can request a token to be alive / valid for. + * Default is `31556926` (1 year) + * settings.realmRequired Require a realm when logging in a user. + * settings.realmDelimiter When set a realm is required. + * settings.resetPasswordTokenTTL Time to live for password reset `AccessToken`. Default is `900` (15 minutes). + * settings.saltWorkFactor The `bcrypt` salt work factor. Default is `10`. + * settings.caseSensitiveEmail Enable case sensitive email. + */ + settings: { http: { path: string }; acls: ACL; emailVerificationRequired: boolean; ttl: number; maxTTL: number; realmRequired: boolean; realmDelimiter: string; resetPasswordTokenTTL: number; saltWorkFactor: number; caseSensitiveEmail: boolean; }; + + /** + * Confirm the user's identity + * @param {Any} userId + * @param {string} token The validation token + * @param {string} redirect URL to redirect the user to once confirmed + * @callback {() => void} callback + * @param {Error} er + */ + + static confirm(userId: any, token: string, redirect: string, callback: (err: Error) => void): void; + + /** + * A default verification token generator which accepts the user the token is + * being generated for and a callback function to indicate completion. + * This one uses the crypto library and 64 random bytes (converted to hex) + * for the token. When used in combination with the user.verify() method this + * function will be called with the `user` object as it's context (`this`) + * @param {any} user The User this token is being generated for. + * @param {() => void} cb The generator must pass back the new token with this function cal + */ + + static generateVerificationToken(user: any, cb: () => void): void; + + /** + * Login a user by with the given `credentials` + * + * ```js + * User.login({username: 'foo', password: 'bar'}, function (err, token) { + * console.log(token.id); + * }); + * ``` + * + * @param {any} credentials username/password or email/password + * @param {string[]|string} [include] Optionally set it to "user" to include + * the user info + * @callback {() => void} callback Callback function + * @param {Error} err Error object + * @param {AccessToken} token Access token if login is successfu + */ + + static login(credentials: any, include?: string[]|string, callback?: (err: Error, token: AccessToken) => void): void; + + /** + * Logout a user with the given accessToken id + * + * ```js + * User.logout('asd0a9f8dsj9s0s3223mk', function (err) { + * console.log(err || 'Logged out'); + * }); + * ``` + * + * @param {string} accessTokenID + * @callback {() => void} callback + * @param {Error} er + */ + + static logout(accessTokenID: string, callback: (err: Error) => void): void; + + /** + * Normalize the credentials + * @param {any} credentials The credential object + * @param {boolean} realmRequired + * @param {string} realmDelimiter The realm delimiter, if not set, no realm is needed + * @returns {any} The normalized credential objec + */ + + static normalizeCredentials(credentials: any, realmRequired: boolean, realmDelimiter: string): any; + + /** + * Create a short lived acess token for temporary login. Allows users + * to change passwords if forgotten + * @options {any} options + * @prop {string} email The user's email address + * @callback {() => void} callback + * @param {Error} er + */ + + static resetPassword(options: {}, callback: (err: Error) => void): void; + + /** + * Create access token for the logged in user. This method can be overridden to + * customize how access tokens are generate + * @param {number} ttl The requested ttl + * @param {any} [options] The options for access token, such as scope, appId + * @callback {() => void} cb The callback function + * @param {string|Error} err The error string or object + * @param {AccessToken} token The generated access token object + */ + + createAccessToken(ttl: number, options?: any, cb?: (err: string|Error, token: AccessToken) => void): void; + + /** + * Compare the given `password` with the users hashed password + * @param {string} password The plain text password + * @callback {() => void} callback Callback function + * @param {Error} err Error object + * @param {boolean} isMatch Returns true if the given `password` matches recor + */ + + hasPassword(password: string, callback: (err: Error, isMatch: boolean) => void): void; + + /** + * Verify a user's identity by sending them a confirmation email + * ```js + * var options = { + * type: 'email', + * to: user.email, + * template: 'verify.ejs', + * redirect: '/', + * tokenGenerator: function (user, cb) { cb("random-token"); } + * }; + * + * user.verify(options, next); + * ``` + * + * @options {any} options + * @property {string} type Must be 'email'. + * @property {string} to Email address to which verification email is sent. + * @property {string} from Sender email addresss, for example + * `'noreply@myapp.com'`. + * @property {string} subject Subject line text. + * @property {string} text Text of email. + * @property {string} template Name of template that displays verification + * page, for example, `'verify.ejs'. + * @property {string} redirect Page to which user will be redirected after + * they verify their email, for example `'/'` for root URI. + * @property {() => void} generateVerificationToken A function to be used to + * generate the verification token. It must accept the user object and a + * callback function. This function should NOT add the token to the user + * object, instead simply execute the callback with the token! User saving + * and email sending will be handled in the `verify()` method + */ + + verify(options: {type: string, to: string, from: string, subject: string, text: string, template: string, redirect: string, generateVerificationToken: () => void}): void; + } +} + +export = l; + diff --git a/loopback/loopback-test.ts b/loopback/loopback-test.ts new file mode 100644 index 0000000000..0c05a377df --- /dev/null +++ b/loopback/loopback-test.ts @@ -0,0 +1,20 @@ +/// +import * as loopback from 'loopback'; +import * as cookieParser from 'cookie-parser'; + +class Server { + app: loopback.LoopBackApplication; + + static boostrap(): Server { + return new Server(); + } + constructor() { + this.app = loopback(); + + this.app.use(cookieParser()); + + this.app.start = function() { + // start the web server + }; + } +} \ No newline at end of file diff --git a/loopback/tsconfig.json b/loopback/tsconfig.json new file mode 100644 index 0000000000..9454529143 --- /dev/null +++ b/loopback/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "loopback-test.ts" + ] +} \ No newline at end of file diff --git a/loopback/tslint.json b/loopback/tslint.json new file mode 100644 index 0000000000..2221e40e4a --- /dev/null +++ b/loopback/tslint.json @@ -0,0 +1 @@ +{ "extends": "../tslint.json" } \ No newline at end of file