diff --git a/mongoose-promise/mongoose-promise-tests.ts b/mongoose-promise/mongoose-promise-tests.ts new file mode 100644 index 0000000000..e7bda80c6d --- /dev/null +++ b/mongoose-promise/mongoose-promise-tests.ts @@ -0,0 +1,46 @@ +/// + +var cb = function () {}; + +var mongopromise: MongoosePromise; +mongopromise.addBack(function (err, arg) { + err.stack; + arg.toFixed(); +}).addBack(function (err, arg1, arg2) { + err.stack; + arg1.toFixed(); + arg2.toFixed(); +}); +mongopromise.addCallback(function (arg) { + arg.toFixed(); +}).addCallback(function (arg1, arg2) { + arg1.toFixed(); + arg2.toFixed(); +}); +mongopromise.addErrback(function (err) { + err.stack; +}).addErrback(cb); +mongopromise.catch(function (err) { + err.stack; +}).catch(cb); +mongopromise.end(); +mongopromise.error(999).error([]); +mongopromise.on('init', cb).on('init', cb); +mongopromise.reject({}).reject('').reject(new Error('hi')); +mongopromise.resolve(new Error('hi'), {}).resolve(); +mongopromise.then(function (arg) { + arg.toFixed(); + return 9; +}, function (err) { + err.stack; + return 9; +}).then(function (arg1, arg2) { + arg1.toFixed(); + arg2.toFixed(); +}); +mongopromise.complete(); +/* static properties */ +MongoosePromise.ES6(function (complete, error) { + complete.apply(this); + error.apply(this); +}); \ No newline at end of file diff --git a/mongoose-promise/mongoose-promise.d.ts b/mongoose-promise/mongoose-promise.d.ts new file mode 100644 index 0000000000..d2622bb6f9 --- /dev/null +++ b/mongoose-promise/mongoose-promise.d.ts @@ -0,0 +1,128 @@ +// Type definitions for Mongoose-Promise 4.5.4 +// Project: http://mongoosejs.com/ +// Definitions by: simonxca +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/* + * These are the default promises included in the Mongoose v4.x + * definitions. They will be deprecated beginning Mongoose V5.x + * in favor of native ES6 Promises. + * + * You can switch the promise library that mongoose uses by: + * + * 1. Including this somewhere in your code: + * mongoose.Promise = YOUR_PROMISE; + * + * 2. Including this somewhere in your main .d.ts file: + * type MongoosePromise = YOUR_PROMISE; + */ + +/* + * http://mongoosejs.com/docs/api.html#promise-js + * + * Callback signatures are from the mPromise type definitions. + */ +interface MongoosePromise { + /** + * Promise constructor. + * Promises are returned from executed queries. + * @param fn a function which will be called when the promise + * is resolved that accepts fn(err, ...){} as signature + * @event err Emits when the promise is rejected + * @event complete Emits when the promise is fulfilled + * @deprecated Mongoose 5.0 will use native promises by default (or bluebird, if native + * promises are not present) but still support plugging in your own ES6-compatible + * promises library. Mongoose 5.0 will not support mpromise. + */ + new(fn?: (err: any, arg: T) => void): MongoosePromise; + new(fn?: (err: any, ...args: T[]) => void): MongoosePromise; +} + +declare class MongoosePromise { + /** + * Adds a single function as a listener to both err and complete. + * It will be executed with traditional node.js argument position when the promise is resolved. + * @deprecated Use onResolve instead. + */ + addBack(listener: (err: any, arg: T) => void): this; + addBack(listener: (err: any, ...args: T[]) => void): this; + + /** + * Adds a listener to the complete (success) event. + * @deprecated Adds a listener to the complete (success) event. + */ + addCallback(listener: (arg: T) => void): this; + addCallback(listener: (...args: T[]) => void): this; + + /** + * Adds a listener to the err (rejected) event. + * @deprecated Use onReject instead. + */ + addErrback(listener: (err: any) => void): this; + + /** ES6-style .catch() shorthand */ + catch(onReject?: (err: any) => void | TRes | PromiseLike): MongoosePromise; + + /** + * Signifies that this promise was the last in a chain of then()s: if a handler passed + * to the call to then which produced this promise throws, the exception will go uncaught. + */ + end(): void; + + /** + * Rejects this promise with err. + * If the promise has already been fulfilled or rejected, not action is taken. + * Differs from #reject by first casting err to an Error if it is not instanceof Error. + */ + error(err: any): this; + + /** + * Adds listener to the event. + * If event is either the success or failure event and the event has already been emitted, + * thelistener is called immediately and passed the results of the original emitted event. + */ + on(event: string, listener: Function): this; + + /** + * Rejects this promise with reason. + * If the promise has already been fulfilled or rejected, not action is taken. + */ + reject(reason: Object | string | Error): this; + + /** + * Resolves this promise to a rejected state if err is passed or a fulfilled state if no err is passed. + * If the promise has already been fulfilled or rejected, not action is taken. + * err will be cast to an Error if not already instanceof Error. + * NOTE: overrides mpromise#resolve to provide error casting. + * @param err error or null + * @param val value to fulfill the promise with + */ + resolve(err?: any, val?: Object): this; + + /** + * Creates a new promise and returns it. If onFulfill or onReject are passed, they are added as + * SUCCESS/ERROR callbacks to this promise after the nextTick. + * Conforms to promises/A+ specification. + */ + then(onFulFill: (arg: T) => void | TRes | PromiseLike, + onReject?: (err: any) => void | TRes | PromiseLike): MongoosePromise; + then(onFulfill: (...args: T[]) => void | TRes | PromiseLike, + onReject?: (err: any) => void | TRes | PromiseLike): MongoosePromise; + + /** + * Fulfills this promise with passed arguments. Alias of mpromise#fulfill. + * @deprecated Use fulfill instead. + */ + complete(args: T): this; + complete(...args: T[]): this; + + /** Fulfills this promise with passed arguments. */ + fulfill(...args: T[]): this; + fulfill(arg: T): this; + + /** ES6-style promise constructor wrapper around mpromise. */ + static ES6(resolver: ( + complete: (...args: TRes[]) => void | TRes | PromiseLike, + error: (e: any) => void | TRes | PromiseLike + ) => void): MongoosePromise; +} \ No newline at end of file diff --git a/mongoose/mongoose-tests.ts b/mongoose/mongoose-tests.ts index de2bffaf05..55249d5248 100644 --- a/mongoose/mongoose-tests.ts +++ b/mongoose/mongoose-tests.ts @@ -1,5 +1,4 @@ /// -/// import * as mongoose from 'mongoose'; var fs = require('fs'); @@ -28,7 +27,7 @@ mongoose.connect(connectUri, { autoIndex: true }, mongos: true -}).then(cb).onReject; +}).then(cb).fulfill(); mongoose.connect(connectUri, function (error) { error.stack; }); @@ -862,10 +861,10 @@ schemaembedded.sparse(true); */ var aggregate: mongoose.Aggregate; aggregate = mongoose.model('ex').aggregate({ $match: { age: { $gte: 21 }}}); -aggregate = new mongoose.Aggregate(); -aggregate = new mongoose.Aggregate({ $project: { a: 1, b: 1 } }); -aggregate = new mongoose.Aggregate({ $project: { a: 1, b: 1 } }, { $skip: 5 }); -aggregate = new mongoose.Aggregate([{ $project: { a: 1, b: 1 } }, { $skip: 5 }]); +aggregate = new mongoose.Aggregate(); +aggregate = new mongoose.Aggregate({ $project: { a: 1, b: 1 } }); +aggregate = new mongoose.Aggregate({ $project: { a: 1, b: 1 } }, { $skip: 5 }); +aggregate = new mongoose.Aggregate([{ $project: { a: 1, b: 1 } }, { $skip: 5 }]); aggregate.addCursorFlag('flag', true).addCursorFlag('', false); aggregate.allowDiskUse(true).allowDiskUse(false, []); aggregate.append({ $project: { field: 1 }}, { $limit: 2 }); @@ -1012,6 +1011,7 @@ mongoose.model('') return (mongoose.model('')).findOne({}).exec(); }).then(function (arg) { arg.save; + return 1; }).catch(function (err) { return 1; }).then(function (arg) { @@ -1054,6 +1054,9 @@ mongoose.Promise = Promise; mongoose.Promise.race; mongoose.Promise.all; +mongoose.model('').findOne() + .exec().addErrback(cb); + /* * section model.js * http://mongoosejs.com/docs/api.html#model-js @@ -1097,10 +1100,8 @@ MongoModel.create({ type: 'jelly bean' }, { type: 'snickers' -}, cb).then(function (a, b, c) { +}, cb).then(function (a) { a.save(); - b.save(); - c.save(); }) MongoModel.create([{ type: 'jelly bean' }, { type: 'snickers' @@ -1125,8 +1126,6 @@ MongoModel.find({ name: /john/i }, 'name friends', function (err, docs) { }) MongoModel.find({ name: /john/i }, null, { skip: 10 }) MongoModel.find({ name: /john/i }, null, { skip: 10 }, function (err, docs) {}); MongoModel.find({ name: /john/i }, null, { skip: 10 }).exec(function (err, docs) {}); -MongoModel.find({ name: /john/i }, null, { skip: 10 }).exec() - .addBack(function (err, docs) {}); MongoModel.findById(999, function (err, adventure) {}); MongoModel.findById(999).exec(cb); MongoModel.findById(999, 'name length', function (err, adventure) { @@ -1192,11 +1191,11 @@ MongoModel.mapReduce({ reduce: cb }, function (err, results) { console.log(results) -}).then(function (model, stats) { +}).then(function (model) { return model.find().where('value').gt(10).exec(); }).then(function (docs) { console.log(docs); -}).then(null, cb).end(); +}).then(null, cb); MongoModel.findById(999, function (err, user) { var opts = [ { path: 'company', match: { x: 1 }, select: 'name' } @@ -1210,7 +1209,7 @@ MongoModel.findById(999, function (err, user) { MongoModel.find(999, function (err, users) { var opts = [{ path: 'company', match: { x: 1 }, select: 'name' }] var promise = MongoModel.populate(users, opts); - promise.then(console.log).end(); + promise.then(console.log); }); MongoModel.populate({ name: 'Indiana Jones', diff --git a/mongoose/mongoose.d.ts b/mongoose/mongoose.d.ts index 8112fc09a1..890928f772 100644 --- a/mongoose/mongoose.d.ts +++ b/mongoose/mongoose.d.ts @@ -6,6 +6,7 @@ /// /// /// +/// /* * Guidelines for maintaining these definitions: @@ -76,7 +77,6 @@ To find a section, CTRL+F and type "section ___.js" declare module "mongoose" { import events = require('events'); import mongodb = require('mongodb'); - import mPromise = require('mpromise'); import stream = require('stream'); /* @@ -138,20 +138,15 @@ declare module "mongoose" { new(...args: any[]): typeof mongoose; } /** - * To use your own promise library: - * mongoose.Promise = bluebird; - * mongoose.Promise = q; + * To assign your own promise library: * - * Note: you will lose type-checking and code completion - * provided by mongoose's built-in promises. + * 1. Include this somewhere in your code: + * mongoose.Promise = YOUR_PROMISE; * - * To use, either: - * - Access its methods using [] - * query.exec()['reduce']().then() // the rest works normally - * - Cast to - * (Model).find().exec().reduce().then() + * 2. Include this somewhere in your main .d.ts file: + * type MongoosePromise = YOUR_PROMISE; */ - static Promise: typeof _mongoose.Promise | any; + static Promise: any; static PromiseProvider: any; static Query: typeof _mongoose.ModelQuery; static Schema: typeof _mongoose.Schema; @@ -261,7 +256,7 @@ declare module "mongoose" { type model = _mongoose.Model; type Model = _mongoose.ModelConstructor; type Mongoose = typeof mongoose; - interface Promise extends _mongoose.Promise {} + interface Promise extends MongoosePromise {} interface Query extends _mongoose.Query {} interface QueryCursor extends _mongoose.QueryCursor {} interface QueryStream extends _mongoose.QueryStream {} @@ -310,13 +305,13 @@ declare module "mongoose" { * and .disconnect().then() are viable. */ static then(onFulfill?: () => void | TRes | PromiseLike, - onRejected?: (err: mongodb.MongoError) => void | TRes | PromiseLike): Promise; + onRejected?: (err: mongodb.MongoError) => void | TRes | PromiseLike): MongoosePromise; /** * Ability to use mongoose object as a pseudo-promise so .connect().then() * and .disconnect().then() are viable. */ - static catch(onRejected?: (err: mongodb.MongoError) => void | TRes | PromiseLike): Promise; + static catch(onRejected?: (err: mongodb.MongoError) => void | TRes | PromiseLike): MongoosePromise; } class CastError extends _mongoose.Error { @@ -427,7 +422,7 @@ declare module "mongoose" { callback?: (err: any) => void): any; /** Closes the connection */ - close(callback?: (err: any) => void): Promise; + close(callback?: (err: any) => void): MongoosePromise; /** * Retrieves a collection, creating it if not cached. @@ -598,7 +593,7 @@ declare module "mongoose" { constructor(query: Query, options: Object): QueryCursor; /** Marks this cursor as closed. Will stop streaming and subsequent calls to next() will error. */ - close(callback?: (error: any, result: any) => void): Promise; + close(callback?: (error: any, result: any) => void): MongoosePromise; /** * Execute fn for every document in the cursor. If fn returns a promise, @@ -606,13 +601,13 @@ declare module "mongoose" { * Returns a promise that resolves when done. * @param callback executed when all docs have been processed */ - eachAsync(fn: (doc: Model) => any, callback?: (err: any) => void): Promise>; + eachAsync(fn: (doc: Model) => any, callback?: (err: any) => void): MongoosePromise>; /** * Get the next document from this cursor. Will return null when there are * no documents left. */ - next(callback?: (err: any) => void): Promise; + next(callback?: (err: any) => void): MongoosePromise; } /* @@ -869,7 +864,7 @@ declare module "mongoose" { * Useful for ES2015 integration. * @returns promise that resolves to the document when population is done */ - execPopulate(): Promise; + execPopulate(): MongoosePromise; /** * Returns the value of a path. @@ -988,8 +983,8 @@ declare module "mongoose" { * @param optional options internal options * @param callback callback called after validation completes, passing an error if one occurred */ - validate(callback?: (err: any) => void): Promise; - validate(optional: Object, callback?: (err: any) => void): Promise; + validate(callback?: (err: any) => void): MongoosePromise; + validate(optional: Object, callback?: (err: any) => void): MongoosePromise; /** * Executes registered validation rules (skipping asynchronous validators) for this document. @@ -1308,7 +1303,7 @@ declare module "mongoose" { * resolved with either the doc(s) or rejected with the error. * Like .then(), but only takes a rejection handler. */ - catch(reject?: (err: any) => void | TRes | PromiseLike): Promise; + catch(reject?: (err: any) => void | TRes | PromiseLike): MongoosePromise; /** * DEPRECATED Alias for circle @@ -1361,8 +1356,8 @@ declare module "mongoose" { equals(val: Object): this; /** Executes the query */ - exec(callback?: (err: any, res: T) => void): Promise; - exec(operation: string | Function, callback?: (err: any, res: T) => void): Promise; + exec(callback?: (err: any, res: T) => void): MongoosePromise; + exec(operation: string | Function, callback?: (err: any, res: T) => void): MongoosePromise; /** Specifies an $exists condition */ exists(val?: boolean): this; @@ -1653,7 +1648,7 @@ declare module "mongoose" { /** Executes this query and returns a promise */ then(resolve?: (res: T) => void | TRes | PromiseLike, - reject?: (err: any) => void | TRes | PromiseLike): Promise; + reject?: (err: any) => void | TRes | PromiseLike): MongoosePromise; /** * Converts this query to a customized, reusable query @@ -1996,10 +1991,10 @@ declare module "mongoose" { // If cursor option is on, could return an object /** Executes the aggregate pipeline on the currently bound Model. */ - exec(callback?: (err: any, result: T) => void): Promise | any; + exec(callback?: (err: any, result: T) => void): MongoosePromise | any; /** Execute the aggregation with explain */ - explain(callback?: (err: any, result: T) => void): Promise; + explain(callback?: (err: any, result: T) => void): MongoosePromise; /** * Appends a new custom $group operator to this aggregate pipeline. @@ -2074,7 +2069,7 @@ declare module "mongoose" { /** Provides promise for aggregate. */ then(resolve?: (val: T) => void | TRes | PromiseLike, - reject?: (err: any) => void | TRes | PromiseLike): Promise + reject?: (err: any) => void | TRes | PromiseLike): MongoosePromise /** * Appends new custom $unwind operator(s) to this aggregate pipeline. @@ -2142,115 +2137,6 @@ declare module "mongoose" { type?: string): this; } - /* - * section promise.js - * http://mongoosejs.com/docs/api.html#promise-js - * - * Callback signatures are from the mPromise type definitions - */ - class Promise extends mPromise { - /** - * Promise constructor. - * Promises are returned from executed queries. - * @param fn a function which will be called when the promise - * is resolved that accepts fn(err, ...){} as signature - * @event err Emits when the promise is rejected - * @event complete Emits when the promise is fulfilled - * @deprecated Mongoose 5.0 will use native promises by default (or bluebird, if native - * promises are not present) but still support plugging in your own ES6-compatible - * promises library. Mongoose 5.0 will not support mpromise. - */ - constructor(fn?: (err: any, arg: T) => void); - constructor(fn?: (err: any, ...args: T[]) => void); - - /** - * Adds a single function as a listener to both err and complete. - * It will be executed with traditional node.js argument position when the promise is resolved. - * @deprecated Use onResolve instead. - */ - addBack(listener: (err: any, arg: T) => void): this; - addBack(listener: (err: any, ...args: T[]) => void): this; - - /** - * Adds a listener to the complete (success) event. - * @deprecated Adds a listener to the complete (success) event. - */ - addCallback(listener: (arg: T) => void): this; - addCallback(listener: (...args: T[]) => void): this; - - /** - * Adds a listener to the err (rejected) event. - * @deprecated Use onReject instead. - */ - addErrback(listener: (err: any) => void): this; - - /** ES6-style .catch() shorthand */ - catch(onReject?: (err: any) => void | TRes | PromiseLike): Promise; - - /** - * Signifies that this promise was the last in a chain of then()s: if a handler passed - * to the call to then which produced this promise throws, the exception will go uncaught. - */ - end(): void; - - /** - * Rejects this promise with err. - * If the promise has already been fulfilled or rejected, not action is taken. - * Differs from #reject by first casting err to an Error if it is not instanceof Error. - */ - error(err: any): this; - - /** - * Adds listener to the event. - * If event is either the success or failure event and the event has already been emitted, - * thelistener is called immediately and passed the results of the original emitted event. - */ - on(event: string, listener: Function): this; - - /** - * Rejects this promise with reason. - * If the promise has already been fulfilled or rejected, not action is taken. - */ - reject(reason: Object | string | NativeError): this; - - /** - * Resolves this promise to a rejected state if err is passed or a fulfilled state if no err is passed. - * If the promise has already been fulfilled or rejected, not action is taken. - * err will be cast to an Error if not already instanceof Error. - * NOTE: overrides mpromise#resolve to provide error casting. - * @param err error or null - * @param val value to fulfill the promise with - */ - resolve(err?: any, val?: Object): this; - - /** - * Creates a new promise and returns it. If onFulfill or onReject are passed, they are added as - * SUCCESS/ERROR callbacks to this promise after the nextTick. - * Conforms to promises/A+ specification. - */ - then(onFulFill: (arg: T) => void | TRes | PromiseLike, - onReject?: (err: any) => void | TRes | PromiseLike): Promise; - then(onFulfill: (...args: T[]) => void | TRes | PromiseLike, - onReject?: (err: any) => void | TRes | PromiseLike): Promise; - - /** - * Fulfills this promise with passed arguments. Alias of mpromise#fulfill. - * @deprecated Use fulfill instead. - */ - complete(args: T): this; - complete(...args: T[]): this; - - /** Fulfills this promise with passed arguments. */ - fulfill(...args: T[]): this; - fulfill(arg: T): this; - - /** ES6-style promise constructor wrapper around mpromise. */ - static ES6(resolver: ( - complete: (...args: TRes[]) => void | TRes | PromiseLike, - error: (e: any) => void | TRes | PromiseLike - ) => void): Promise; - } - /* * section model.js * http://mongoosejs.com/docs/api.html#model-js @@ -2310,7 +2196,7 @@ declare module "mongoose" { * @param ... aggregation pipeline operator(s) or operator array */ aggregate(...aggregations: Object[]): Aggregate; - aggregate(...aggregationsWithCallback: Object[]): Promise; + aggregate(...aggregationsWithCallback: Object[]): MongoosePromise; /** Counts number of matching documents in a database collection. */ count(conditions: Object, callback?: (err: any, count: number) => void): Query; @@ -2320,9 +2206,9 @@ declare module "mongoose" { * does new MyModel(doc).save() for every doc in docs. * Triggers the save() hook. */ - create(docs: any[], callback?: (err: any, res: Model[]) => void): Promise[]>; - create(...docs: Object[]): Promise>; - create(...docsWithCallback: Object[]): Promise>; + create(docs: any[], callback?: (err: any, res: Model[]) => void): MongoosePromise[]>; + create(...docs: Object[]): MongoosePromise>; + create(...docsWithCallback: Object[]): MongoosePromise>; /** * Adds a discriminator type. @@ -2341,8 +2227,8 @@ declare module "mongoose" { * @param options internal options * @param cb optional callback */ - ensureIndexes(callback?: (err: any) => void): Promise; - ensureIndexes(options: Object, callback?: (err: any) => void): Promise; + ensureIndexes(callback?: (err: any) => void): MongoosePromise; + ensureIndexes(options: Object, callback?: (err: any) => void): MongoosePromise; /** * Finds documents. @@ -2477,9 +2363,9 @@ declare module "mongoose" { * document. * This function does not trigger save middleware. */ - insertMany(docs: any[], callback?: (error: any, docs: Model[]) => void): Promise[]>; - insertMany(doc: any, callback?: (error: any, doc: Model) => void): Promise>; - insertMany(...docsWithCallback: Object[]): Promise>; + insertMany(docs: any[], callback?: (error: any, docs: Model[]) => void): MongoosePromise[]>; + insertMany(doc: any, callback?: (error: any, doc: Model) => void): MongoosePromise>; + insertMany(...docsWithCallback: Object[]): MongoosePromise>; /** * Executes a mapReduce command. @@ -2489,7 +2375,7 @@ declare module "mongoose" { mapReduce( o: ModelMapReduceOption, Key, Value>, callback?: (err: any, res: any) => void - ): Promise; + ): MongoosePromise; /** * Populates document references. @@ -2498,9 +2384,9 @@ declare module "mongoose" { * @param callback Optional callback, executed upon completion. Receives err and the doc(s). */ populate(docs: Object[], options: ModelPopulateOptions | ModelPopulateOptions[], - callback?: (err: any, res: Model[]) => void): Promise[]>; + callback?: (err: any, res: Model[]) => void): MongoosePromise[]>; populate(docs: Object, options: ModelPopulateOptions | ModelPopulateOptions[], - callback?: (err: any, res: Model) => void): Promise>; + callback?: (err: any, res: Model) => void): MongoosePromise>; /** Removes documents from the collection. */ remove(conditions: Object, callback?: (err: any) => void): Query; @@ -2532,7 +2418,7 @@ declare module "mongoose" { * Removes this document from the db. * @param fn optional callback */ - remove(fn?: (err: any, product: Model) => void): Promise>; + remove(fn?: (err: any, product: Model) => void): MongoosePromise>; /** * Saves this document. @@ -2541,7 +2427,7 @@ declare module "mongoose" { * @param options.validateBeforeSave set to false to save without validating. * @param fn optional callback */ - save(fn?: (err: any, product: Model, numAffected: number) => void): Promise>; + save(fn?: (err: any, product: Model, numAffected: number) => void): MongoosePromise>; /** Base Mongoose instance the model uses. */ base: typeof mongoose;