From eb62b43bcfe2a1ec98c99dc2224d7fe23f3c7e5d Mon Sep 17 00:00:00 2001 From: Karim Alibhai Date: Sun, 20 May 2018 16:07:19 -0400 Subject: [PATCH 1/3] Fix: loopback async function types --- types/loopback/index.d.ts | 653 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 620 insertions(+), 33 deletions(-) diff --git a/types/loopback/index.d.ts b/types/loopback/index.d.ts index 087ce2aadd..05a3730d79 100644 --- a/types/loopback/index.d.ts +++ b/types/loopback/index.d.ts @@ -18,6 +18,13 @@ import { NextFunction, RequestHandler } from "express"; declare function l(): l.LoopBackApplication; declare namespace l { + /** + * General type for a callback to an async function. + */ + type CallbackWithoutResult = (err: Error | null) => any + type CallbackWithResult = (err: Error | null, result: T) => any + type CallbackWithMultipleResults = (err: Error | null, arg0: T, arg1: G) => any + /** * The `App` object represents a Loopback application * The App object extends [Express](expressjs.com/api.html#express) and @@ -1183,7 +1190,16 @@ declare namespace l { * @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): Promise | void; + static bulkUpdate(updates: any[], options: any, callback: CallbackWithoutResult): void; + + /** + * 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): Promise; /** * Get the changes to a model since the specified checkpoint. Provide a filter object @@ -1194,13 +1210,29 @@ declare namespace l { * @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): Promise | void; + static changes(since: number, filter: any, callback: CallbackWithResult): 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. + * @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): Promise; /** * Create a checkpoint * @param {() => void} callback */ - static checkpoint(callback?: () => void): Promise | void; + static checkpoint(callback?: () => void): void; + + /** + * Create a checkpoint + */ + static checkpoint(): Promise; /** * Return the number of records that match the optional "where" filter. @@ -1214,7 +1246,21 @@ declare namespace l { * @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): Promise | void; + static count(where: any, callback: CallbackWithResult): 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): Promise; /** * Create new instance of Model, and save to database @@ -1223,14 +1269,28 @@ declare namespace l { * @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: T|T[]) => void): Promise | void; + static create(data: any | any[], callback: CallbackWithResult): 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 + * @returns {T | T[]} Model instances or null + */ + static create(data?: any|any[]): Promise; /** * 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): Promise | void; + static createChangeStream(options: {where: any}, callback: CallbackWithResult): 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. + * @returns {any} changes + */ + static createChangeStream(options: {where: any}): Promise; /** * Create an update list (for `Model.bulkUpdate()`) from a delta list @@ -1238,7 +1298,14 @@ declare namespace l { * @param {Array} deltas * @param {() => void} callback */ - static createUpdates(deltas: any[], callback?: () => void): Promise | void; + static createUpdates(deltas: any[], callback: CallbackWithoutResult): void; + + /** + * Create an update list (for `Model.bulkUpdate()`) from a delta list + * (result of `Change.diff()`) + * @param {Array} deltas + */ + static createUpdates(deltas: any[]): Promise; /** * Get the current checkpoint ID @@ -1246,7 +1313,13 @@ declare namespace l { * @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): Promise | void; + static currentCheckpoint(callback: CallbackWithResult): void; + + /** + * Get the current checkpoint ID + * @returns {Promise} resolves to currentCheckpointId + */ + static currentCheckpoint(): Promise; /** * Destroy all model instances that match the optional `where` specification @@ -1262,7 +1335,20 @@ declare namespace l { * @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): Promise<{ info: any, infoCount: number}> | void; + static destroyAll(where: any, callback: CallbackWithMultipleResults): 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) + * + * @returns {Promise<{ count: number }>} number of instances (rows, documents) destroyed + */ + static destroyAll(where?: any): Promise<{ info: any, infoCount: number}>; /** * Destroy model instance with the specified ID. @@ -1270,7 +1356,13 @@ declare namespace l { * @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): Promise | void; + static destroyById(id: any, callback: CallbackWithoutResult): void; + + /** + * Destroy model instance with the specified ID. + * @param {*} id The ID value of model instance to delete. + */ + static destroyById(id: any): Promise; /** * Get a set of deltas and conflicts since the given checkpoint @@ -1281,7 +1373,15 @@ declare namespace l { * @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): Promise | void; + static diff(since: number, remoteChanges: any[], callback: CallbackWithResult): 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. + */ + static diff(since: number, remoteChanges: any[]): Promise; /** * Enable the tracking of changes made to the model. Usually for replication. @@ -1295,7 +1395,24 @@ declare namespace l { * @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): Promise | void; + static exists(id: any, callback: CallbackWithResult): void; + + /** + * Check whether a model instance exists in database + * @param {id} id Identifier of object (primary key value) + */ + static exists(id: any): Promise; + + /** + * Find all model instances that match `filter` specification. + * See [Querying models](docs.strongloop.com/display/LB/Querying+models) + * @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( + callback: CallbackWithResult + ): void; /** * Find all model instances that match `filter` specification. @@ -1322,8 +1439,60 @@ declare namespace l { * @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): Promise | void; + filter: { + fields?: string|any|any[]; + include?: string|any|any[]; + limit?: number; + order?: string; + skip?: number; + where?: any; + }, + callback: CallbackWithResult + ): 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) + */ + static find( + filter?: { + fields?: string|any|any[]; + include?: string|any|any[]; + limit?: number; + order?: string; + skip?: number; + where?: any; + } + ): Promise; + + /** + * Find object by ID with an optional filter for include/fields + * @param {*} id Primary key value + * @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, + callback: CallbackWithResult + ): void; /** * Find object by ID with an optional filter for include/fields @@ -1337,7 +1506,43 @@ declare namespace l { * @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: T) => void): Promise | void; + static findById( + id: any, + filter: { + fields?: string|any|any[]; + include?: string|any|any[]; + }, + callback: CallbackWithResult + ): 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). + */ + static findById( + id: any, + filter?: { + fields?: string|any|any[]; + include?: string|any|any[]; + }, + ): Promise; + + /** + * Find one model instance that matches `filter` specification. + * Same as `find`, but limited to one result; + * Returns object, not collection + * @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( + callback: CallbackWithResult + ): void; /** * Find one model instance that matches `filter` specification. @@ -1363,14 +1568,63 @@ declare namespace l { * @param {Array} model First model instance that matches the filter or null if none found */ static findOne( - filter?: { + filter: { fields?: string|any|any[]; include?: string|any|any[]; order?: string; skip?: number; where?: any; }, - callback?: (err: Error, instance: T) => void): Promise | void; + callback: CallbackWithResult + ): 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) + */ + static findOne( + filter?: { + fields?: string|any|any[]; + include?: string|any|any[]; + order?: string; + skip?: number; + where?: any; + } + ): Promise; + + /** + * 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 + * + * @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, + callback: CallbackWithMultipleResults + ): void; /** * Finds one record matching the optional filter object. If not found, creates @@ -1404,7 +1658,7 @@ declare namespace l { */ static findOrCreate( data: any, - filter?: { + filter: { fields?: string | any | any[]; include?: string | any | any[]; limit?: number; @@ -1412,7 +1666,46 @@ declare namespace l { skip?: number; where?: any; }, - callback?: (err: Error, instance: any, created: boolean) => void): Promise<{instance: T, created: boolean}> | void; + callback: CallbackWithMultipleResults + ): 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. + */ + static findOrCreate( + data: any, + filter?: { + fields?: string | any | any[]; + include?: string | any | any[]; + limit?: number; + order?: string; + skip?: number; + where?: any; + } + ): Promise<{instance: T, created: boolean}>; /** * Get the `Change` model. @@ -1432,7 +1725,12 @@ declare namespace l { * @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): Promise | void; + static getSourceId(callback: CallbackWithResult): void; + + /** + * Get the source identifier for this model or dataSource + */ + static getSourceId(): Promise; /** * Handle a change error. Override this method in a subclassing model to customize @@ -1447,7 +1745,29 @@ declare namespace l { * @callback {() => void} callback * @param {Error} er */ - static rectifyChange(id: any, callback?: (err: Error) => void): Promise | void; + static rectifyChange(id: any, callback: CallbackWithoutResult): void; + + /** + * Specify that a change to the model with the given ID has occurred + * @param {*} id The ID of the model that has changed. + */ + static rectifyChange(id: any): Promise; + + /** + * 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. + * @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, + callback: CallbackWithResult + ): void; /** * Replace attributes for a model instance whose id is the first input @@ -1461,7 +1781,45 @@ declare namespace l { * @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: T) => void): Promise | void; + static replaceById( + id: any, + data: any, + options: { + validate: boolean; + }, + callback: CallbackWithResult + ): 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. + */ + static replaceById( + id: any, + data: any, + options?: { + validate: boolean; + } + ): Promise; + + /** + * 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. + * @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, + callback: CallbackWithResult + ): void; /** * Replace or insert a model instance; replace existing record if one is found, @@ -1474,7 +1832,28 @@ declare namespace l { * @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, instance: T) => void): Promise | void; + static replaceOrCreate( + data: any, + options: { + validate: boolean; + }, + callback: CallbackWithResult + ): 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. + */ + static replaceOrCreate( + data: any, + options?: { + validate: boolean; + } + ): Promise; /** * Replicate changes since the given checkpoint to the given target model @@ -1485,7 +1864,7 @@ declare namespace l { * @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" + * @param {any} checkpoints The new checkpoints to use as the "since" * argument for the next replication */ static replicate( @@ -1496,6 +1875,18 @@ declare namespace l { callback?: (err: Error, conflicts: Conflict[], param: any) => void ): Promise<{conflicts: Conflict[], params: any}> | void; + /** + * Update multiple instances that match the where clause. + * @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( + callback: CallbackWithMultipleResults + ): void; + /** * Update multiple instances that match the where clause. * @@ -1521,7 +1912,65 @@ declare namespace l { * @param {number} info.count number of instances (rows, documents) updated. * */ - static updateAll(where?: any, data?: any, callback?: (err: Error, info: any, infoCount: number) => void): Promise | void; + static updateAll( + whereOrData: any, + callback: CallbackWithMultipleResults + ): 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: CallbackWithMultipleResults + ): 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. + */ + static updateAll( + where?: any, + data?: any + ): Promise; /** * Update or insert a model instance @@ -1530,7 +1979,21 @@ declare namespace l { * @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, instance: T) => void): Promise | void; + static upsert( + data: any, + callback: CallbackWithResult + ): 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 + ): Promise; /** * Update or insert a model instance based on the search criteria. @@ -1548,14 +2011,40 @@ declare namespace l { * @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, instance: T) => void): Promise | void; + static upsertWithWhere( + data: any, + callback: CallbackWithResult + ): 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. + */ + static upsertWithWhere( + data: any + ): Promise; /** * Deletes the model from persistence. * Triggers `destroy` hook (async) before and after destroying object. * @param {() => void} callback Callback function */ - destroy(callback?: () => void): Promise | void; + destroy(callback: CallbackWithoutResult): void; + + /** + * Deletes the model from persistence. + * Triggers `destroy` hook (async) before and after destroying object. + */ + destroy(): Promise; /** * Get the `id` value for the `PersistedModel` @@ -1581,7 +2070,25 @@ declare namespace l { * @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: T) => void): Promise | void; + reload(callback: CallbackWithResult): void; + + /** + * Reload object from persistence. Requires `id` member of `object` to be able to call `find`. + */ + reload(): Promise; + + /** + * Replace attributes for a model instance and persist it into the datasource. + * Performs validation before replacing + * @param {any} data Data to replace. + * @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, + callback: CallbackWithResult + ): void; /** * Replace attributes for a model instance and persist it into the datasource. @@ -1593,7 +2100,38 @@ declare namespace l { * @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: T) => void): Promise | void; + replaceAttributes( + data: any, + options: { + validate: boolean + }, + callback: CallbackWithResult + ): 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. + */ + replaceAttributes( + data: any, + options?: { + validate: boolean + } + ): Promise; + + /** + * Save model instance. If the instance doesn't have an ID, then calls [create](#persistedmodelcreatedata-cb) instead. + * Triggers: validate, save, update, or create. + * @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( + callback: CallbackWithResult + ): void; /** * Save model instance. If the instance doesn't have an ID, then calls [create](#persistedmodelcreatedata-cb) instead. @@ -1606,7 +2144,28 @@ declare namespace l { * @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: T) => void): Promise | void; + save( + options: { + validate: boolean; + throws: boolean + }, + callback: CallbackWithResult + ): 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. + */ + save( + options?: { + validate: boolean; + throws: boolean + } + ): Promise; /** * Set the correct `id` property for the `PersistedModel`. Uses the `setId` method if the model is attached to @@ -1625,7 +2184,22 @@ declare namespace l { * @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: T) => void): Promise | void; + updateAttribute( + name: string, + value: any, + callback: CallbackWithResult + ): void; + + /** + * Update a single attribute. + * Equivalent to `updateAttributes({name: 'value'}, cb) + * @param {string} name Name of property. + * @param {any} value Value of property. + */ + updateAttribute( + name: string, + value: any + ): Promise; /** * Update set of attributes. Performs validation before updating @@ -1635,7 +2209,19 @@ declare namespace l { * @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: T) => void): Promise | void; + updateAttributes( + data: any, + callback: CallbackWithResult + ): void; + + /** + * Update set of attributes. Performs validation before updating + * Triggers: `validation`, `save` and `update` hooks + * @param {any} data Data to update. + */ + updateAttributes( + data: any + ): Promise; // **NOTE** Deprecate for v3.x // /** @@ -1688,6 +2274,7 @@ declare namespace l { // */ // createany(options: any, optionsWhere: any, callback: (err: Error, changes: any) => void): void; } + // END OF PERSISTED MODEL /** * Serve the LoopBack favicon. From bf05c947a54306f299b7954bc0733325bbb78878 Mon Sep 17 00:00:00 2001 From: Karim Alibhai Date: Sun, 20 May 2018 16:18:05 -0400 Subject: [PATCH 2/3] Fix: test issues --- types/loopback/index.d.ts | 27 ++++++++++++++++++--------- types/loopback/loopback-tests.ts | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/types/loopback/index.d.ts b/types/loopback/index.d.ts index 05a3730d79..aa9bfb2b8b 100644 --- a/types/loopback/index.d.ts +++ b/types/loopback/index.d.ts @@ -21,9 +21,9 @@ declare namespace l { /** * General type for a callback to an async function. */ - type CallbackWithoutResult = (err: Error | null) => any - type CallbackWithResult = (err: Error | null, result: T) => any - type CallbackWithMultipleResults = (err: Error | null, arg0: T, arg1: G) => any + type CallbackWithoutResult = (err: Error | null) => any; + type CallbackWithResult = (err: Error | null, result: T) => any; + type CallbackWithMultipleResults = (err: Error | null, arg0: T, arg1: G) => any; /** * The `App` object represents a Loopback application @@ -1210,7 +1210,7 @@ declare namespace l { * @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: CallbackWithResult): void; + static changes(since: number, filter: any, callback: CallbackWithResult): void; /** * Get the changes to a model since the specified checkpoint. Provide a filter object @@ -1283,14 +1283,23 @@ declare namespace l { * @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: CallbackWithResult): void; + static createChangeStream( + options: { + where: any; + }, + callback: CallbackWithResult + ): 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. * @returns {any} changes */ - static createChangeStream(options: {where: any}): Promise; + static createChangeStream( + options: { + where: any; + } + ): Promise; /** * Create an update list (for `Model.bulkUpdate()`) from a delta list @@ -1314,7 +1323,7 @@ declare namespace l { * @param {number} currentCheckpointId Current checkpoint ID */ static currentCheckpoint(callback: CallbackWithResult): void; - + /** * Get the current checkpoint ID * @returns {Promise} resolves to currentCheckpointId @@ -1449,7 +1458,7 @@ declare namespace l { }, callback: CallbackWithResult ): void; - + /** * Find all model instances that match `filter` specification. * See [Querying models](docs.strongloop.com/display/LB/Querying+models) @@ -1514,7 +1523,7 @@ declare namespace l { }, callback: CallbackWithResult ): void; - + /** * Find object by ID with an optional filter for include/fields * @param {*} id Primary key value diff --git a/types/loopback/loopback-tests.ts b/types/loopback/loopback-tests.ts index 359e6977b6..cb015fc0bd 100644 --- a/types/loopback/loopback-tests.ts +++ b/types/loopback/loopback-tests.ts @@ -36,7 +36,7 @@ class Server { console.dir(data.name); } - model.findOne({}, (err: Error, instance: TestModel) => { + model.findOne({}, (err: Error | null, instance: TestModel) => { if (err) { console.dir(err); } From 56cf16cff3a35fd3473ef98c449f10302fda1dad Mon Sep 17 00:00:00 2001 From: Karim Alibhai Date: Sun, 20 May 2018 16:19:36 -0400 Subject: [PATCH 3/3] Add: self to definitions by --- types/loopback/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/loopback/index.d.ts b/types/loopback/index.d.ts index aa9bfb2b8b..c743db10ce 100644 --- a/types/loopback/index.d.ts +++ b/types/loopback/index.d.ts @@ -4,6 +4,7 @@ // Tim Schumacher // Sequoia McDowell // Mike Crowe +// Karim Alibhai // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3