2019-05-08 15:45:37 +00:00
|
|
|
// Copyright IBM Corp. 2018,2019. All Rights Reserved.
|
2018-05-02 23:21:49 +00:00
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
|
|
|
import {EventEmitter} from 'events';
|
|
|
|
import {AnyObject, Options} from './common';
|
|
|
|
import {DataSource} from './datasource';
|
2020-02-28 09:07:26 +00:00
|
|
|
import {Listener, OperationHookContext} from './observer-mixin';
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Property types
|
|
|
|
*/
|
|
|
|
export type PropertyType =
|
|
|
|
| string
|
|
|
|
| Function
|
|
|
|
| {[property: string]: PropertyType};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Property definition
|
|
|
|
*/
|
|
|
|
export interface PropertyDefinition extends AnyObject {
|
|
|
|
type?: PropertyType;
|
2019-01-24 08:39:50 +00:00
|
|
|
id?: boolean | number;
|
2018-05-02 23:21:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Schema definition
|
|
|
|
*/
|
|
|
|
export interface Schema {
|
|
|
|
name: string;
|
2019-01-24 08:39:50 +00:00
|
|
|
properties: ModelProperties;
|
|
|
|
settings?: ModelSettings;
|
2018-05-02 23:21:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ID definition
|
|
|
|
*/
|
|
|
|
export interface IdDefinition {
|
|
|
|
name: string;
|
|
|
|
id: number;
|
|
|
|
property: AnyObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Index definition
|
|
|
|
*/
|
|
|
|
export interface IndexDefinition extends AnyObject {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Column metadata
|
|
|
|
*/
|
|
|
|
export interface ColumnMetadata extends AnyObject {
|
|
|
|
name: string;
|
|
|
|
}
|
|
|
|
|
2019-01-24 08:39:50 +00:00
|
|
|
/**
|
|
|
|
* Definition of model properties, for example
|
|
|
|
* ```ts
|
|
|
|
* {
|
|
|
|
* name: {type: String, required: true},
|
|
|
|
* }
|
|
|
|
* ```
|
|
|
|
*/
|
|
|
|
export interface ModelProperties {
|
|
|
|
[name: string]: PropertyDefinition
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Model settings, for example
|
|
|
|
* ```ts
|
|
|
|
* {
|
|
|
|
* strict: true,
|
|
|
|
* }
|
|
|
|
* ```
|
|
|
|
*/
|
|
|
|
export interface ModelSettings extends AnyObject {
|
|
|
|
strict?: boolean;
|
|
|
|
forceId?: boolean;
|
|
|
|
}
|
|
|
|
|
2018-05-02 23:21:49 +00:00
|
|
|
/**
|
|
|
|
* Model definition
|
|
|
|
*/
|
|
|
|
export declare class ModelDefinition extends EventEmitter implements Schema {
|
|
|
|
name: string;
|
2019-01-24 08:39:50 +00:00
|
|
|
properties: ModelProperties;
|
2018-05-02 23:21:49 +00:00
|
|
|
rawProperties: AnyObject;
|
2019-01-24 08:39:50 +00:00
|
|
|
settings?: ModelSettings;
|
2018-05-02 23:21:49 +00:00
|
|
|
relations?: AnyObject[];
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
modelBuilder: ModelBuilder | null | undefined,
|
|
|
|
name: string,
|
2019-01-24 08:39:50 +00:00
|
|
|
properties?: ModelProperties,
|
|
|
|
settings?: ModelSettings,
|
2018-05-02 23:21:49 +00:00
|
|
|
);
|
|
|
|
constructor(modelBuilder: ModelBuilder | null | undefined, schema: Schema);
|
|
|
|
|
|
|
|
tableName(connectorType: string): string;
|
|
|
|
columnName(connectorType: string, propertyName: string): string;
|
|
|
|
columnNames(connectorType: string): string[];
|
|
|
|
columnMetadata(connectorType: string, propertyName: string): ColumnMetadata;
|
|
|
|
|
|
|
|
ids(): IdDefinition[];
|
|
|
|
idName(): string;
|
|
|
|
idNames(): string[];
|
|
|
|
|
|
|
|
defineProperty(
|
|
|
|
propertyName: string,
|
|
|
|
propertyDefinition: PropertyDefinition,
|
|
|
|
): void;
|
|
|
|
indexes(): {[name: string]: IndexDefinition};
|
|
|
|
build(forceRebuild?: boolean): AnyObject;
|
|
|
|
toJSON(forceRebuild?: boolean): AnyObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-05-10 17:19:15 +00:00
|
|
|
* Base class for LoopBack 3.x models
|
2018-05-02 23:21:49 +00:00
|
|
|
*/
|
|
|
|
export declare class ModelBase {
|
|
|
|
static dataSource?: DataSource;
|
|
|
|
static modelName: string;
|
|
|
|
static definition: ModelDefinition;
|
2019-01-24 08:39:50 +00:00
|
|
|
static readonly base: typeof ModelBase;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extend the model with the specified model, properties, and other settings.
|
|
|
|
* For example, to extend an existing model:
|
|
|
|
*
|
|
|
|
* ```js
|
|
|
|
* const Customer = User.extend('Customer', {
|
|
|
|
* accountId: String,
|
|
|
|
* vip: Boolean
|
|
|
|
* });
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @param className Name of the new model being defined.
|
|
|
|
* @param subClassProperties child model properties, added to base model
|
|
|
|
* properties.
|
|
|
|
* @param subClassSettings child model settings such as relations and acls,
|
|
|
|
* merged with base model settings.
|
|
|
|
*/
|
|
|
|
static extend<ChildModel extends typeof ModelBase = typeof ModelBase>(
|
|
|
|
modelName: string,
|
|
|
|
properties?: ModelProperties,
|
|
|
|
settings?: ModelSettings,
|
|
|
|
): ChildModel;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Attach the model class to a data source
|
|
|
|
* @param ds The data source
|
|
|
|
*/
|
|
|
|
static attachTo(ds: DataSource): void;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get model property type.
|
|
|
|
* @param {string} propName Property name
|
|
|
|
* @returns {string} Name of property type
|
|
|
|
*/
|
|
|
|
static getPropertyType(propName: string): string | null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if property is hidden.
|
|
|
|
* @param {string} propertyName Property name
|
|
|
|
* @returns {Boolean} true or false if hidden or not.
|
|
|
|
*/
|
|
|
|
static isHiddenProperty(propertyName: string): boolean;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if property is protected.
|
|
|
|
* @param {string} propertyName Property name
|
|
|
|
* @returns {Boolean} true or false if protected or not.
|
|
|
|
*/
|
|
|
|
static isProtectedProperty(propertyName: string): boolean;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets properties defined with 'updateOnly' flag set to true from the model.
|
|
|
|
* This flag is also set to true internally for the id property, if this
|
|
|
|
* property is generated and IdInjection is true.
|
|
|
|
* @returns {updateOnlyProps} List of properties with updateOnly set to true.
|
|
|
|
*/
|
|
|
|
static getUpdateOnlyProperties(): string[];
|
|
|
|
|
|
|
|
/**
|
2018-05-10 17:19:15 +00:00
|
|
|
* Constructor for ModelBase
|
2018-05-02 23:21:49 +00:00
|
|
|
*
|
2018-05-10 17:19:15 +00:00
|
|
|
* NOTE: We have to use `constructor(...args: any[]);` so that it can be used
|
|
|
|
* for `return class extends superClass`.
|
2018-05-02 23:21:49 +00:00
|
|
|
*
|
|
|
|
* @param {AnyObject} data Initial object data
|
|
|
|
* @param {Options} options An object to control the instantiation
|
|
|
|
*/
|
2018-05-10 17:19:15 +00:00
|
|
|
constructor(...args: any[]);
|
|
|
|
// constructor(data: AnyObject, options?: Options);
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert the model instance to a plain json object
|
|
|
|
*/
|
|
|
|
toJSON(): AnyObject;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Populate properties from a JSON object
|
|
|
|
* @param obj The source object
|
|
|
|
*/
|
|
|
|
fromObject(obj: AnyObject): void;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert model instance to a plain JSON object.
|
|
|
|
* Returns a canonical object representation (no getters and setters).
|
|
|
|
*
|
2018-05-10 17:19:15 +00:00
|
|
|
* @param options Options for the conversion
|
|
|
|
* @property {boolean} onlySchema Restrict properties to dataSource only.
|
2018-05-02 23:21:49 +00:00
|
|
|
* Default is false. If true, the function returns only properties defined
|
|
|
|
* in the schema; Otherwise it returns all enumerable properties.
|
2018-05-10 17:19:15 +00:00
|
|
|
* @property {boolean} removeHidden Boolean flag as part of the transformation.
|
2018-05-02 23:21:49 +00:00
|
|
|
* If true, then hidden properties should not be brought out.
|
2018-05-10 17:19:15 +00:00
|
|
|
* @property {boolean} removeProtected Boolean flag as part of the transformation.
|
2018-05-02 23:21:49 +00:00
|
|
|
* If true, then protected properties should not be brought out.
|
|
|
|
* @returns {object} returns Plain JSON object
|
|
|
|
*/
|
2018-05-10 17:19:15 +00:00
|
|
|
toObject(options?: Options): AnyObject;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Define a property on the model.
|
|
|
|
* @param {string} prop Property name
|
|
|
|
* @param definition Various property configuration
|
|
|
|
*/
|
|
|
|
defineProperty(
|
|
|
|
propertyName: string,
|
|
|
|
definition: Partial<PropertyDefinition>,
|
|
|
|
): void;
|
|
|
|
|
|
|
|
getDataSource(): DataSource;
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {string} anotherClass could be string or class. Name of the class
|
|
|
|
* or the class itself
|
|
|
|
* @param {Object} options An object to control the instantiation
|
|
|
|
* @returns {ModelClass}
|
|
|
|
*/
|
|
|
|
static mixin(
|
|
|
|
anotherClass: string | ModelBaseClass | object,
|
|
|
|
options?: Options,
|
|
|
|
): ModelBaseClass;
|
2020-02-28 09:07:26 +00:00
|
|
|
|
|
|
|
// ObserverMixin members are added as static methods, this is difficult to
|
|
|
|
// describe in TypeScript in a way that's easy to use by consumers.
|
|
|
|
// As a workaround, we include a copy of ObserverMixin members here.
|
|
|
|
//
|
|
|
|
// See also https://github.com/microsoft/TypeScript/issues/5863#issuecomment-410887254
|
|
|
|
// for more information about using `this` in static members.
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register an asynchronous observer for the given operation (event).
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
|
|
|
* Registers a `before save` observer for a given model.
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* MyModel.observe('before save', function filterProperties(ctx, next) {
|
|
|
|
* if (ctx.options && ctx.options.skipPropertyFilter) return next();
|
|
|
|
* if (ctx.instance) {
|
|
|
|
* FILTERED_PROPERTIES.forEach(function(p) {
|
|
|
|
* ctx.instance.unsetAttribute(p);
|
|
|
|
* });
|
|
|
|
* } else {
|
|
|
|
* FILTERED_PROPERTIES.forEach(function(p) {
|
|
|
|
* delete ctx.data[p];
|
|
|
|
* });
|
|
|
|
* }
|
|
|
|
* next();
|
|
|
|
* });
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @param {String} operation The operation name.
|
|
|
|
* @callback {function} listener The listener function. It will be invoked with
|
|
|
|
* `this` set to the model constructor, e.g. `User`.
|
|
|
|
* @end
|
|
|
|
*/
|
|
|
|
static observe<T extends typeof ModelBase>(
|
|
|
|
this: T,
|
|
|
|
operation: string,
|
|
|
|
listener: Listener<OperationHookContext<T>>,
|
|
|
|
): void;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unregister an asynchronous observer for the given operation (event).
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* MyModel.removeObserver('before save', function removedObserver(ctx, next) {
|
|
|
|
* // some logic user want to apply to the removed observer...
|
|
|
|
* next();
|
|
|
|
* });
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @param {String} operation The operation name.
|
|
|
|
* @callback {function} listener The listener function.
|
|
|
|
* @end
|
|
|
|
*/
|
|
|
|
static removeObserver<T extends typeof ModelBase>(
|
|
|
|
this: T,
|
|
|
|
operation: string,
|
|
|
|
listener: Listener<OperationHookContext<T>>,
|
|
|
|
): Listener<OperationHookContext<T>> | undefined;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unregister all asynchronous observers for the given operation (event).
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
|
|
|
* Remove all observers connected to the `before save` operation.
|
|
|
|
*
|
|
|
|
* ```javascript
|
|
|
|
* MyModel.clearObservers('before save');
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @param {String} operation The operation name.
|
|
|
|
* @end
|
|
|
|
*/
|
|
|
|
static clearObservers(operation: string): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export type ModelBaseClass = typeof ModelBase;
|
|
|
|
|
|
|
|
export declare class ModelBuilder extends EventEmitter {
|
|
|
|
static defaultInstance: ModelBuilder;
|
|
|
|
|
|
|
|
models: {[name: string]: ModelBaseClass};
|
|
|
|
definitions: {[name: string]: ModelDefinition};
|
2019-01-24 08:39:50 +00:00
|
|
|
settings: ModelSettings;
|
|
|
|
|
|
|
|
defaultModelBaseClass: typeof ModelBase;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
getModel(name: string, forceCreate?: boolean): ModelBaseClass;
|
|
|
|
|
|
|
|
getModelDefinition(name: string): ModelDefinition | undefined;
|
|
|
|
|
|
|
|
define(
|
|
|
|
className: string,
|
2019-01-24 08:39:50 +00:00
|
|
|
properties?: ModelProperties,
|
|
|
|
settings?: ModelSettings,
|
2018-05-02 23:21:49 +00:00
|
|
|
parent?: ModelBaseClass,
|
|
|
|
): ModelBaseClass;
|
|
|
|
|
|
|
|
defineProperty(
|
|
|
|
modelName: string,
|
|
|
|
propertyName: string,
|
|
|
|
propertyDefinition: AnyObject,
|
|
|
|
): void;
|
|
|
|
|
|
|
|
defineValueType(type: string, aliases?: string[]): void;
|
|
|
|
|
|
|
|
extendModel(modelName: string, properties: AnyObject): void;
|
|
|
|
|
|
|
|
getSchemaName(name?: string): string;
|
|
|
|
|
|
|
|
resolveType(type: any): any;
|
|
|
|
|
|
|
|
buildModels(
|
|
|
|
schemas: AnyObject,
|
|
|
|
createModel?: Function,
|
|
|
|
): {[name: string]: ModelBaseClass};
|
|
|
|
|
|
|
|
buildModelFromInstance(
|
|
|
|
name: string,
|
|
|
|
json: AnyObject,
|
|
|
|
options: Options,
|
|
|
|
): ModelBaseClass;
|
|
|
|
}
|
|
|
|
|
2018-06-29 06:35:22 +00:00
|
|
|
/**
|
|
|
|
* An extension of the built-in Partial<T> type which allows partial values
|
|
|
|
* in deeply nested properties too.
|
|
|
|
*/
|
|
|
|
export type DeepPartial<T> = { [P in keyof T]?: DeepPartial<T[P]>; };
|
|
|
|
|
2018-05-02 23:21:49 +00:00
|
|
|
/**
|
|
|
|
* Union export type for model instance or plain object representing the model
|
|
|
|
* instance
|
|
|
|
*/
|
2018-06-29 06:35:22 +00:00
|
|
|
export type ModelData<T extends ModelBase = ModelBase> = T | DeepPartial<T>;
|