diff --git a/mongoose/mongoose-tests.ts b/mongoose/mongoose-tests.ts
new file mode 100644
index 000000000..38c469ca1
--- /dev/null
+++ b/mongoose/mongoose-tests.ts
@@ -0,0 +1,366 @@
+///
+
+var fs = require('fs');
+import mongoose = require('mongoose');
+
+var createInstance = new mongoose.Mongoose();
+
+var Schema = mongoose.Schema;
+var CreateSchema = new Schema({});
+
+mongoose.connect('mongodb://user:pass@localhost:port/database');
+mongoose.connect('mongodb://hostA:27501,hostB:27501', { mongos: true });
+
+var conn: mongoose.Connection = mongoose.createConnection('mongodb://user:pass@localhost:port/database');
+conn = mongoose.createConnection('mongodb://user:pass@localhost:port/database,mongodb://anotherhost:port,mongodb://yetanother:port', { replset: { strategy: 'ping', rs_name: 'testSet' }});
+conn = mongoose.createConnection('localhost', 'database', 27014);
+conn = mongoose.createConnection('localhost', 'database', 27014, { server: { auto_reconnect: false }, user: 'username', pass: 'mypassword' });
+conn = mongoose.createConnection();
+conn.open('localhost', 'database', 27014, {});
+
+var db = mongoose.createConnection();
+db.openSet("mongodb://user:pwd@localhost:27020/testing,mongodb://example.com:27020,mongodb://localhost:27019");
+db.openSet('mongodb://mongosA:27501,mongosB:27501', 'db', { mongos: true }, (err: any) => {});
+db.close();
+
+var collection = db.collection('collection1');
+
+mongoose.connection.on('error', (err: any) => {});
+mongoose.disconnect();
+
+mongoose.set('test', 1234567890);
+var value = mongoose.get('test');
+mongoose.set('debug', true);
+
+interface IActor extends mongoose.Document {
+ name: string;
+}
+mongoose.model('Actor', new Schema({ name: String }));
+db.model('Actor', new Schema({ name: String }));
+var schema: mongoose.Schema = new Schema({ name: String }, { collection: 'actor' });
+schema.set('collection', 'actor');
+var Model = mongoose.model('Actor', schema, 'actor');
+
+var names: string[] = mongoose.modelNames();
+var names: string[] = db.modelNames();
+mongoose.plugin((schema: mongoose.Schema) => {
+}, { index: true });
+
+
+var aggregate = new mongoose.Aggregate();
+var aggregate = new mongoose.Aggregate({ $project: { a: 1, b: 1 } });
+var aggregate = new mongoose.Aggregate({ $project: { a: 1, b: 1 } }, { $skip: 5 });
+var aggregate = new mongoose.Aggregate([{ $project: { a: 1, b: 1 } }, { $skip: 5 }]);
+aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
+aggregate.append([{ $match: { daw: 'Logic Audio X' }} ]);
+aggregate.group({ _id: "$department" });
+aggregate.skip(10);
+aggregate.limit(10);
+aggregate.match({ department: { $in: [ "sales", "engineering" ] } });
+aggregate.near({
+ near: [40.724, -73.997],
+ distanceField: "dist.calculated", // required
+ maxDistance: 0.008,
+ query: { type: "public" },
+ includeLocs: "dist.location",
+ uniqueDocs: true,
+ num: 5
+});
+aggregate.project("a b -_id");
+aggregate.project({a: 1, b: 1, _id: 0});
+aggregate.project({
+ newField: '$b.nested',
+ plusTen: { $add: ['$val', 10]},
+ sub: {
+ name: '$a'
+ }
+});
+aggregate.project({ salary_k: { $divide: [ "$salary", 1000 ] } });
+aggregate.sort({ field: 'asc', test: -1 });
+aggregate.sort('field -test');
+aggregate.unwind("tags");
+aggregate.unwind("a", "b", "c");
+var p = aggregate.exec();
+aggregate.read('primaryPreferred').exec((err: any, result: {}) => {});
+
+
+var p = new mongoose.Promise;
+var p2 = p.then(function() { throw new Error('shucks') }).end();
+setTimeout(function() {
+ p.fulfill({});
+}, 10);
+var promise = new mongoose.Promise();
+promise.then(function (meetups: number) {
+ return new mongoose.Promise();
+}).then(function (people: string[]) {
+ if (people.length < 10000) {
+ throw new Error('Too few people!!!');
+ } else {
+ throw new Error('Still need more people!!!');
+ }
+}).then(null, function (err: Error) {
+}).end();
+
+
+Model.findOne({ name: 'john' }, (err: any, doc: mongoose.Document) => {
+ doc.invalidate('size', 'must be less than 20', 14);
+ doc.validate((err: any) => { });
+
+ doc.set('documents.0.title', 'changed');
+ doc.get('documents.0');
+ doc.set({
+ 'path' : 1,
+ 'path2' : {
+ 'path' : 2
+ }
+ });
+ doc.set('path', 'value', { strict: false });
+ doc.set('path3', '1', Number);
+ doc.get('path3', Number);
+ doc.id;
+ doc._id;
+
+ doc.isModified();
+ doc.isModified('documents');
+ doc.isModified('documents.0.title');
+ doc.isDirectModified('documents.0.title');
+ doc.isDirectModified('documents');
+ doc.isSelected('name');
+
+ doc.markModified('mixed.type');
+ doc.populate('user');
+ doc.populate('other', (err: any, doc: mongoose.Document) => {});
+ doc.populated('author');
+ doc.save();
+
+ doc.toJSON({ getters: true, virtuals: false });
+ var data: any = doc.toObject();
+ delete data['age'];
+ delete data['weight'];
+ data['isAwesome'] = true;
+});
+
+Model.model('User').findById('id', (err: any, res: IActor) => {});
+Model.count({ type: 'jungle' }, (err: any, count: number) => {});
+Model.remove((err: any, res: IActor[]) => {});
+Model.save((err: any, res: IActor, numberAffected: number) => {});
+Model.create({ type: 'jelly bean' }, { type: 'snickers' }, (err: any, res1: IActor, res2: IActor) => {});
+Model.create({ type: 'jawbreaker' });
+Model.distinct('url', { clicks: {$gt: 100}}, (err: any, result: IActor[]) => {});
+Model.distinct('url');
+
+Model.aggregate(
+ { $group: { _id: null, maxBalance: { $max: '$balance' }}},
+ { $project: { _id: 0, maxBalance: 1 }},
+ (err: any, res: IActor[]) => {});
+Model.aggregate()
+ .group({ _id: null, maxBalance: { $max: '$balance' } })
+ .select('-id maxBalance')
+ .exec((err: any, res: IActor[]) => {});
+Model.ensureIndexes((err) => {});
+
+Model.find({ name: 'john', age: { $gte: 18 }});
+Model.find({ name: 'john', age: { $gte: 18 }}, (err: any, docs: IActor[]) => {});
+Model.find({ name: /john/i }, 'name friends', (err: any, docs: IActor[]) => {});
+Model.find({ name: /john/i }, null, { skip: 10 });
+Model.find({ name: /john/i }, null, { skip: 10 }, (err: any, docs: IActor[]) => {});
+Model.find({ name: /john/i }, null, { skip: 10 }).exec((err: any, docs: IActor[]) => {});
+var query = Model.find({ name: /john/i }, null, { skip: 10 });
+var promise1 = query.exec();
+promise1.addBack((err: any, docs: IActor[]) => {});
+
+Model.findById('id', (err: any, res: IActor) => {});
+Model.findById('id').exec((err: any, res: IActor) => {});
+Model.findById('id', 'name length', (err: any, res: IActor) => {});
+Model.findById('id', '-length').exec((err: any, res: IActor) => {});
+Model.findById('id', 'name', { lean: true }, (err: any, res: IActor) => {});
+Model.findById('id', 'name').lean().exec((err: any, res: IActor) => {});
+Model.findByIdAndRemove('id1', { select: 'name' }, (err: any, res: IActor) => {});
+Model.findByIdAndRemove('id1', { select: 'name' }).exec((err: any, res: IActor) => {});
+Model.findByIdAndRemove('id1', (err: any, res: IActor) => {});
+Model.findByIdAndRemove('id1').exec((err: any, res: IActor) => {});
+Model.findByIdAndUpdate('id2', { $set: { name: 'jason borne' }}, { upsert: true }, (err: any, res: IActor) => {});
+
+Model.findOne({ type: 'iphone' }, (err: any, res: IActor) => {});
+Model.findOne({ type: 'iphone' }).exec((err: any, res: IActor) => {});
+Model.findOne({ type: 'iphone' }, 'name', (err: any, res: IActor) => {});
+Model.findOne({ type: 'iphone' }, 'name').exec((err: any, res: IActor) => {});
+Model.findOne({ type: 'iphone' }, 'name', { lean: true }, (err: any, res: IActor) => {});
+Model.findOne({ type: 'iphone' }, 'name', { lean: true }).exec((err: any, res: IActor) => {});
+Model.findOne({ type: 'iphone' }).select('name').lean().exec((err: any, res: IActor) => {});
+Model.findOneAndRemove({ type: 'iphone' }, { select: 'name' }, (err: any, res: IActor) => {});
+Model.findOneAndRemove({ type: 'iphone' }, { select: 'name' }).exec((err: any, res: IActor) => {});
+Model.findOneAndUpdate({ type: 'iphone' }, { $set: { name: 'jason borne' }}, { upsert: true }, (err: any, res: IActor) => {});
+
+Model.geoNear([1, 3], { maxDistance : 5, spherical : true }, (err: any, res: IActor[]) => {});
+Model.geoNear({ type : "Point", coordinates : [9,9] }, { maxDistance : 5, spherical : true }, (err: any, res: IActor[]) => {});
+Model.geoSearch({ type : "house" }, { near: [10, 10], maxDistance: 5 }, (err: any, res: IActor[]) => {});
+
+var o = {
+ map: function () { this.emit(this.name, 1) },
+ reduce: function (k: string, vals: IActor[]) { return vals.length },
+};
+Model.mapReduce(o, (err: any, res: any[]) => {});
+
+Model.findById('id', (err: any, res: IActor) => {
+ var opts = [
+ { path: 'company', match: { x: 1 }, select: 'name' },
+ { path: 'notes', options: { limit: 10 }, model: 'override' }
+ ];
+ Model.populate(res, opts, (err: any, res: IActor) => {});
+});
+Model.find({ type: 'iphone' }, (err: any, res: IActor[]) => {
+ var opts = [{ path: 'company', match: { x: 1 }, select: 'name' }];
+ var promise = Model.populate(res, opts);
+ promise.then(console.log).end();
+});
+Model.populate({ name: 'Test A' }, { path: 'weapon', model: 'Weapon' }, (err: any, user: IActor) => {});
+Model.populate([
+ { name: 'User hoge' },
+ { name: 'User fuga' },
+], { path: 'weapon' }, (err: any, users: IActor[]) => {});
+
+Model.remove({ title: 'baby born from alien father' }, (err: any) => {});
+var query2 = Model.remove({ _id: 'id' });
+query2.exec();
+Model.update({ age: { $gt: 18 } }, { oldEnough: true }, (err: any, numberAffected: number, raw: any) => {});
+Model.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, (err: any, numberAffected: number, raw: any) => {});
+Model.update({ _id: 'id' }, { $set: { text: 'changed' }}).exec();
+
+Model.where('age').gte(21).lte(65).exec((err: any, res: IActor[]) => {});
+var query3 =Model
+ .where('age').gt(21).lt(65)
+ .where('name', /^b/i).all('type', 1);
+query3.all(25);
+query3.and([{ color: 'green' }, { status: 'ok' }]);
+query3.batchSize(100);
+query3.where('loc').within().box([40.73083, -73.99756], [40.741404, -73.988135]);
+query3.where('loc').within().circle({ center: [50, 50], radius: 10, unique: true });
+query3.circle('loc', { center: [50, 50], radius: 10, unique: true });
+query3.comment('login query');
+query3.where({ 'color': 'black' }).count();
+query3.count({ color: 'black' }).count((err: any, count: number) => {});
+query3.count({ color: 'black' }, (err: any, count: number) => {});
+query3.where({ color: 'black' }).count((err: any, count: number) => {});
+query3.elemMatch('comment', { author: 'autobot', votes: {$gte: 5}});
+query3.where('comment').elemMatch({ author: 'autobot', votes: {$gte: 5}});
+query.elemMatch('comment', (elem: mongoose.Query) => {
+ elem.where('author').equals('autobot');
+ elem.where('votes').gte(5);
+});
+query3.where('age').equals(49);
+query3.where('age', 49);
+query3.exec();
+query3.exec('update');
+query3.where('name').exists();
+query3.where('name').exists(true);
+query3.find().exists('name');
+query3.where('name').exists(false);
+query3.find().exists('name', false);
+query3.find({ name: 'Los Pollos Hermanos' }).find((err: any, res: IActor[]) => {});
+query3.where('loc').within().geometry({ type: 'Polygon', coordinates: [[[ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ]]] });
+query3.find().where('age').gt(21);
+query3.find().gt('age', 21);
+query3.hint({ indexA: 1, indexB: -1});
+query3.where('path').intersects().geometry({ type: 'LineString', coordinates: [[180.0, 11.0], [180, 9.0]] });
+query3.where('path').intersects({ type: 'LineString', coordinates: [[180.0, 11.0], [180, 9.0]] });
+query3.maxScan(100);
+query3.where('loc').near({ center: [10, 10] });
+query3.where('loc').near({ center: [10, 10], maxDistance: 5 });
+query3.where('loc').near({ center: [10, 10], maxDistance: 5, spherical: true });
+query3.near('loc', { center: [10, 10], maxDistance: 5 });
+query3.where('loc').nearSphere({ center: [10, 10], maxDistance: 5 });
+query3.nor([{ color: 'green' }, { status: 'ok' }]);
+query3.or([{ color: 'red' }, { status: 'emergency' }]);
+query3.where('loc').within().polygon([10,20], [13, 25], [7,15]);
+query3.polygon('loc', [10,20], [13, 25], [7,15]);
+
+query3.findOne().populate('owner').exec((err: any, res: IActor[]) => {});
+query3.find().populate({
+ path: 'owner',
+ select: 'name',
+ match: { color: 'black' },
+ options: { sort: { name: -1 }}
+}).exec((err: any, res: IActor[]) => {});
+query3.find().populate('owner', 'name', null, {sort: { name: -1 }}).exec((err: any, res: IActor[]) => {});
+
+query3.read('primary');
+query3.read('p');
+query3.read('primaryPreferred');
+query3.read('pp');
+query3.read('secondary');
+query3.read('s');
+query3.read('secondaryPreferred');
+query3.read('sp');
+query3.read('nearest');
+query3.read('n');
+query3.read('s', [{ dc:'sf', s: 1 },{ dc:'ma', s: 2 }]);
+query3.remove({ artist: 'Anne Murray' }, (err: any, res: IActor[]) => {});
+query3.select('a b -c');
+query3.select({a: 1, b: 1, c: 0});
+query3.select('+path');
+query3.where('tags').size(0);
+query3.skip(100).limit(20);
+query3.slaveOk();
+query3.slaveOk(true);
+query3.slaveOk(false);
+query3.slice('comments', -5);
+query3.slice('comments', [10, 5])
+query3.where('comments').slice(5);
+query3.where('comments').slice([-10, 5]);
+query3.snapshot();
+query3.snapshot(true);
+query3.snapshot(false);
+query3.sort({ field: 'asc', test: -1 });
+query3.sort('field -test');
+Model.find({ name: /^hello/ }).stream({ transform: JSON.stringify }).pipe(fs.createWriteStream('./test.json'));
+var stream = Model.find({ name: /^hello/ }).stream();
+stream
+ .on('data', (doc: IActor) => {})
+ .on('error', (err: any) => {})
+ .on('close', () => {});
+
+query3.tailable();
+query3.tailable(false);
+var AdvQuery = query3.toConstructor();
+query3.update({ title: 'words' });
+query3.update({ $set: { title: 'words' }});
+query3.update({ name: /^match/ }, { $set: { arr: [] }}, { multi: true }, (err: any, row: number, raw: any) => {});
+
+query3.where('loc').within({ center: [50,50], radius: 10, unique: true, spherical: true });
+query3.where('loc').within({ box: [[40.73, -73.9], [40.7, -73.988]] });
+query3.where('loc').within({ polygon: [[],[],[],[]] });
+query3.where('loc').within([], [], []); // polygon
+query3.where('loc').within([], []); // box
+query3.where('loc').within({ type: 'LineString', coordinates: [] }); // geometry
+
+mongoose.Query.use$geoWithin = false;
+
+
+var ToySchema = new Schema({});
+ToySchema.add({ name: 'string', color: 'string', price: 'number' });
+schema.eachPath(function(path: string, value: any) {});
+schema.index({ first: 1, last: -1 });
+schema.indexes();
+schema.method('meow', function() {
+ console.log('meeeeeoooooooooooow');
+});
+var Kitty = mongoose.model('Kitty', schema);
+var fizz: any = new Kitty({ name: 'kitty' });
+fizz.meow();
+schema.method({
+ purr: function() {},
+ scratch: function() {},
+});
+schema.path('name');
+schema.path('name', Number);
+schema.pathType('name');
+schema.plugin(function() {});
+schema.post('save', function(doc: IActor) {});
+schema.pre('save', function(next: () => void) {});
+schema.requiredPaths();
+schema.static('findByName', function(name: string, callback: () => void) {});
+schema.virtual('display_name')
+ .get(function(): string { return this.name; })
+ .set((value: string): void => {});
+
diff --git a/mongoose/mongoose.d.ts b/mongoose/mongoose.d.ts
new file mode 100644
index 000000000..e9057abc7
--- /dev/null
+++ b/mongoose/mongoose.d.ts
@@ -0,0 +1,453 @@
+// Type definitions for Mongoose 3.8.5
+// Project: http://mongoosejs.com/
+// Definitions by: horiuchi
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module "mongoose" {
+ function connect(uri: string, options?: ConnectionOption, callback?: (err: any) => void): Mongoose;
+ function createConnection(): Connection;
+ function createConnection(uri: string, options?: ConnectionOption): Connection;
+ function createConnection(host: string, database_name: string, port?: number, options?: ConnectionOption): Connection;
+ function disconnect(callback?: (err?: any) => void): Mongoose;
+
+ function model(name: string, schema: Schema, collection?: string, skipInit?: boolean): Model;
+ function modelNames(): string[];
+ function plugin(plugin: (schema: Schema, options?: Object) => void, options?: Object): Mongoose;
+
+ function get(key: string): any;
+ function set(key: string, value: any): void;
+
+ var mongo: any;
+ var mquery: any;
+ var version: string;
+ var connection: Connection;
+
+ export class Mongoose {
+ connect(uri: string, options?: ConnectionOption, callback?: (err: any) => void): Mongoose;
+ createConnection(): Connection;
+ createConnection(uri: string, options?: Object): Connection;
+ createConnection(host: string, database_name: string, port?: number, options?: ConnectionOption): Connection;
+ disconnect(callback?: (err?: any) => void): Mongoose;
+ get(key: string): any;
+ model(name: string, schema: Schema, collection?: string, skipInit?: boolean): Model;
+ modelNames(): string[];
+ plugin(plugin: (schema: Schema, options?: Object) => void, options?: Object): Mongoose;
+ set(key: string, value: any): void;
+
+ mongo: any;
+ mquery: any;
+ version: string;
+ connection: Connection;
+ }
+
+ export interface Connection extends NodeJS.EventEmitter {
+ constructor(base: Mongoose): Connection;
+
+ close(callback?: (err: any) => void): Connection;
+ collection(name: string, options?: Object): Collection;
+ model(name: string, schema: Schema, collection?: string): Model;
+ modelNames(): string[];
+ open(host: string, database?: string, port?: number, options?: ConnectionOption, callback?: (err: any) => void): Connection;
+ openSet(uris: string, database?: string, options?: ConnectionSetOption, callback?: (err: any) => void): Connection;
+
+ db: any;
+ collections: {[index: string]: Collection};
+ readyState: number;
+ }
+ export interface ConnectionOption {
+ db?: any;
+ server?: any;
+ replset?: any;
+ user?: string;
+ pass?: string;
+ auth?: any;
+ }
+ export interface ConnectionSetOption extends ConnectionOption {
+ mongos?: boolean;
+ }
+
+ export interface Collection {
+ }
+
+
+ export class SchemaType { }
+ export class VirtualType {
+ get(fn: Function): VirtualType;
+ set(fn: Function): VirtualType;
+ }
+ export module Types {
+ export class ObjectId {}
+ }
+
+ export class Schema {
+ static Types: {
+ String: String;
+ ObjectId: Types.ObjectId;
+ OId: Types.ObjectId;
+ Mixed: any;
+ };
+ constructor(schema?: Object, options?: Object);
+
+ add(obj: Object, prefix?: string): void;
+ eachPath(fn: (path: string, type: any) => void): Schema;
+ get(key: string): any;
+ index(fields: Object, options?: Object): Schema;
+ indexes(): void;
+ method(name: string, fn: Function): Schema;
+ method(method: Object): Schema;
+ path(path: string): any;
+ path(path: string, constructor: any): Schema;
+ pathType(path: string): string;
+ plugin(plugin: (schema: Schema, options?: Object) => void, options?: Object): Schema;
+ post(method: string, fn: Function): Schema;
+ pre(method: string, callback: Function): Schema;
+ requiredPaths(): string[];
+ set(key: string, value: any): void;
+ static(name: string, fn: Function): Schema;
+ virtual(name: string, options?: Object): VirtualType;
+ virtualpath(name: string): VirtualType;
+ }
+ export interface SchemaOption {
+ autoIndex?: boolean;
+ bufferCommands?: boolean;
+ capped?: boolean;
+ collection?: string;
+ id?: boolean;
+ _id?: boolean;
+ minimize?: boolean;
+ read?: string;
+ safe?: boolean;
+ shardKey?: boolean;
+ strict?: boolean;
+ toJSON?: Object;
+ toObject?: Object;
+ versionKey?: boolean;
+ }
+
+ export interface Model {
+ new(doc: Object): T;
+
+ aggregate(...aggregations: Object[]): Aggregate;
+ aggregate(aggregation: Object, callback: (err: any, res: T[]) => void): Promise;
+ aggregate(aggregation1: Object, aggregation2: Object, callback: (err: any, res: T[]) => void): Promise;
+ aggregate(aggregation1: Object, aggregation2: Object, aggregation3: Object, callback: (err: any, res: T[]) => void): Promise;
+ count(conditions: Object, callback?: (err: any, count: number) => void): Query;
+
+ create(doc: Object, fn?: (err: any, res: T) => void): Promise;
+ create(doc1: Object, doc2: Object, fn?: (err: any, res1: T, res2: T) => void): Promise;
+ create(doc1: Object, doc2: Object, doc3: Object, fn?: (err: any, res1: T, res2: T, res3: T) => void): Promise;
+ discriminator(name: string, schema: Schema): Model;
+ distinct(field: string, callback?: (err: any, res: T[]) => void): Query;
+ distinct(field: string, conditions: Object, callback?: (err: any, res: T[]) => void): Query;
+ ensureIndexes(callback: (err: any) => void): Promise;
+
+ find(cond: Object, callback?: (err: any, res: T[]) => void): Query;
+ find(cond: Object, fields: Object, callback?: (err: any, res: T[]) => void): Query;
+ find(cond: Object, fields: Object, options: Object, callback?: (err: any, res: T[]) => void): Query;
+ findById(id: string, callback?: (err: any, res: T) => void): Query;
+ findById(id: string, fields: Object, callback?: (err: any, res: T) => void): Query;
+ findById(id: string, fields: Object, options: Object, callback?: (err: any, res: T) => void): Query;
+ findByIdAndRemove(id: string, callback?: (err: any, res: T) => void): Query;
+ findByIdAndRemove(id: string, options: Object, callback?: (err: any, res: T) => void): Query;
+ findByIdAndUpdate(id: string, update: Object, callback?: (err: any, res: T) => void): Query;
+ findByIdAndUpdate(id: string, update: Object, options: FindAndUpdateOption, callback?: (err: any, res: T) => void): Query;
+ findOne(cond: Object, callback?: (err: any, res: T) => void): Query;
+ findOne(cond: Object, fields: Object, callback?: (err: any, res: T) => void): Query;
+ findOne(cond: Object, fields: Object, options: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndRemove(cond: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndRemove(cond: Object, options: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndUpdate(cond: Object, update: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndUpdate(cond: Object, update: Object, options: FindAndUpdateOption, callback?: (err: any, res: T) => void): Query;
+
+ geoNear(point: { type: string; coordinates: number[] }, options: Object, callback?: (err: any, res: T[]) => void): Query;
+ geoNear(point: number[], options: Object, callback?: (err: any, res: T[]) => void): Query;
+ geoSearch(cond: Object, options: GeoSearchOption, callback?: (err: any, res: T[]) => void): Query;
+ increment(): T;
+ mapReduce(options: MapReduceOption, callback?: (err: any, res: MapReduceResult[]) => void): Promise[]>;
+ mapReduce(options: MapReduceOption2, callback?: (err: any, res: MapReduceResult[]) => void): Promise[]>;
+ model(name: string): Model;
+
+ populate(doc: U, options: Object, callback?: (err: any, res: U) => void): Promise;
+ populate(doc: U[], options: Object, callback?: (err: any, res: U[]) => void): Promise;
+ update(cond: Object, update: Object, callback?: (err: any, affectedRows: number, raw: any) => void): Query;
+ update(cond: Object, update: Object, options: Object, callback?: (err: any, affectedRows: number, raw: any) => void): Query;
+ remove(cond: Object, callback?: (err: any) => void): Query<{}>;
+ save(callback?: (err: any, result: T, numberAffected: number) => void): Query;
+ where(path: string, val?: Object): Query;
+
+ $where(argument: string): Query;
+ $where(argument: Function): Query;
+
+ base: Mongoose;
+ collection: Collection;
+ db: any;
+ discriminators: any;
+ modelName: string;
+ schema: Schema;
+ }
+ export interface FindAndUpdateOption {
+ new?: boolean;
+ upsert?: boolean;
+ sort?: Object;
+ select?: Object;
+ }
+ export interface GeoSearchOption {
+ near: number[];
+ maxDistance: number;
+ limit?: number;
+ lean?: boolean;
+ }
+ export interface MapReduceOption {
+ map: () => void;
+ reduce: (key: Key, vals: T[]) => Val;
+ query?: Object;
+ limit?: number;
+ keeptemp?: boolean;
+ finalize?: (key: Key, val: Val) => Val;
+ scope?: Object;
+ jsMode?: boolean;
+ verbose?: boolean;
+ out?: {
+ inline?: number;
+ replace?: string;
+ reduce?: string;
+ merge?: string;
+ };
+ }
+ export interface MapReduceOption2 {
+ map: string;
+ reduce: (key: Key, vals: T[]) => Val;
+ query?: Object;
+ limit?: number;
+ keeptemp?: boolean;
+ finalize?: (key: Key, val: Val) => Val;
+ scope?: Object;
+ jsMode?: boolean;
+ verbose?: boolean;
+ out?: {
+ inline?: number;
+ replace?: string;
+ reduce?: string;
+ merge?: string;
+ };
+ }
+ export interface MapReduceResult {
+ _id: Key;
+ value: Val;
+ }
+
+ export class Query {
+ exec(callback?: (err: any, res: T) => void): Promise;
+ exec(operation: string, callback?: (err: any, res: T) => void): Promise;
+ exec(operation: Function, callback?: (err: any, res: T) => void): Promise;
+
+ all(val: number): Query;
+ all(path: string, val: number): Query;
+ and(array: Object[]): Query;
+ box(val: Object): Query;
+ box(a: number[], b: number[]): Query;
+ batchSize(val: number): Query;
+ cast(model: Model, obj: Object): U;
+ //center(): Query;
+ //centerSphere(path: string, val: Object): Query;
+ circle(area: Object): Query;
+ circle(path: string, area: Object): Query;
+ comment(val: any): Query;
+ count(callback?: (err: any, count: number) => void): Query;
+ count(criteria: Object, callback?: (err: any, count: number) => void): Query;
+ distinct(callback?: (err: any, res: T) => void): Query;
+ distinct(field: string, callback?: (err: any, res: T) => void): Query;
+ distinct(criteria: Object, field: string, callback?: (err: any, res: T) => void): Query;
+ distinct(criteria: Query, field: string, callback?: (err: any, res: T) => void): Query;
+ elemMatch(criteria: Object): Query;
+ elemMatch(criteria: (elem: Query) => void): Query;
+ elemMatch(path: string, criteria: Object): Query;
+ elemMatch(path: string, criteria: (elem: Query) => void): Query;
+ equals(val: Object): Query;
+ exists(val?: boolean): Query;
+ exists(path: string, val?: boolean): Query;
+ find(callback?: (err: any, res: T) => void): Query;
+ find(criteria: Object, callback?: (err: any, res: T) => void): Query;
+ findOne(callback?: (err: any, res: T) => void): Query;
+ findOne(criteria: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndRemove(callback?: (err: any, res: T) => void): Query;
+ findOneAndRemove(cond: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndRemove(cond: Object, options: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndUpdate(callback?: (err: any, res: T) => void): Query;
+ findOneAndUpdate(update: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndUpdate(cond: Object, update: Object, callback?: (err: any, res: T) => void): Query;
+ findOneAndUpdate(cond: Object, update: Object, options: FindAndUpdateOption, callback?: (err: any, res: T) => void): Query;
+ geometry(object: Object): Query;
+ gt(val: number): Query;
+ gt(path: string, val: number): Query;
+ gte(val: number): Query;
+ gte(path: string, val: number): Query;
+ hint(val: Object): Query;
+ in(val: any[]): Query;
+ in(path: string, val: any[]): Query;
+ intersects(arg?: Object): Query;
+ lean(bool?: boolean): Query;
+ limit(val: number): Query;
+ lt(val: number): Query;
+ lt(path: string, val: number): Query;
+ lte(val: number): Query;
+ lte(path: string, val: number): Query;
+ maxDistance(val: number): Query;
+ maxDistance(path: string, val: number): Query;
+ maxScan(val: number): Query;
+ merge(source: Query): Query;
+ merge(source: Object): Query;
+ mod(val: number[]): Query;
+ mod(path: string, val: number[]): Query;
+ ne(val: any): Query;
+ ne(path: string, val: any): Query;
+ near(val: Object): Query;
+ near(path: string, val: Object): Query;
+ nearSphere(val: Object): Query;
+ nearSphere(path: string, val: Object): Query;
+ nin(val: any[]): Query;
+ nin(path: string, val: any[]): Query;
+ nor(array: Object[]): Query;
+ or(array: Object[]): Query;
+ polygon(...coordinatePairs: number[][]): Query;
+ polygon(path: string, ...coordinatePairs: number[][]): Query;
+ populate(path: string, select?: string, match?: Object, options?: Object): Query;
+ populate(path: string, select: string, model: string, match?: Object, options?: Object): Query;
+ populate(opt: PopulateOption): Query;
+ read(pref: string, tags?: Object[]): Query;
+ regex(val: RegExp): Query;
+ regex(path: string, val: RegExp): Query;
+ remove(callback?: (err: any, res: T) => void): Query;
+ remove(criteria: Object, callback?: (err: any, res: T) => void): Query;
+ select(arg: string): Query;
+ select(arg: Object): Query;
+ setOptions(options: Object): Query;
+ size(val: number): Query;
+ size(path: string, val: number): Query;
+ skip(val: number): Query;
+ slaveOk(v?: boolean): Query;
+ slice(val: number): Query;
+ slice(val: number[]): Query;
+ slice(path: string, val: number): Query;
+ slice(path: string, val: number[]): Query;
+ snapshot(v?: boolean): Query;
+ sort(arg: Object): Query;
+ sort(arg: string): Query;
+ stream(options?: { transform?: Function; }): QueryStream;
+ tailable(v?: boolean): Query;
+ toConstructor(): Query;
+ update(callback?: (err: any, affectedRows: number, doc: T) => void): Query;
+ update(doc: Object, callback?: (err: any, affectedRows: number, doc: T) => void): Query;
+ update(criteria: Object, doc: Object, callback?: (err: any, affectedRows: number, doc: T) => void): Query;
+ update(criteria: Object, doc: Object, options: Object, callback?: (err: any, affectedRows: number, doc: T) => void): Query;
+ where(path?: string, val?: any): Query;
+ where(path?: Object, val?: any): Query;
+ within(val?: Object): Query;
+ within(coordinate: number[], ...coordinatePairs: number[][]): Query;
+
+ $where(argument: string): Query;
+ $where(argument: Function): Query;
+
+ static use$geoWithin: boolean;
+ }
+
+ export interface PopulateOption {
+ path: string;
+ select?: string;
+ model?: string;
+ match?: Object;
+ options?: Object;
+ }
+
+ export interface QueryStream extends NodeJS.EventEmitter {
+ destory(err?: any): void;
+ pause(): void;
+ resume(): void;
+ pipe(destination: T, options?: { end?: boolean; }): T;
+ paused: number;
+ readable: boolean;
+ }
+
+ export interface Document {
+ id?: string;
+ _id: string;
+
+ equals(doc: Document): boolean;
+ get(path: string, type?: new(...args: any[]) => any): any;
+ inspect(options?: Object): string;
+ invalidate(path: string, errorMsg: string, value: any): void;
+ invalidate(path: string, error: Error, value: any): void;
+ isDirectModified(path: string): boolean;
+ isInit(path: string): boolean;
+ isModified(path?: string): boolean;
+ isSelected(path: string): boolean;
+ markModified(path: string): void;
+ modifiedPaths(): string[];
+ populate(callback?: (err: any, res: T) => void): Document;
+ populate(path?: string, callback?: (err: any, res: T) => void): Document;
+ populate(opt: PopulateOption, callback?: (err: any, res: T) => void): Document;
+ populated(path: string): any;
+ remove(callback?: (err: any) => void): Query;
+ save(callback?: (err: any, res: T) => void): void;
+ set(path: string, val: any, type?: new(...args: any[]) => any, options?: Object): void;
+ set(path: string, val: any, options?: Object): void;
+ set(value: Object): void;
+ toJSON(options?: Object): Object;
+ toObject(options?: Object): Object;
+ toString(): string;
+ update(doc: Object, options: Object, callback: (err: any, affectedRows: number, raw: any) => void): Query;
+ validate(cb: (err: any) => void): void;
+
+ isNew: boolean;
+ errors: Object;
+ schema: Object;
+ }
+
+
+ export class Aggregate {
+ constructor(...options: Object[]);
+
+ append(...options: Object[]): Aggregate;
+ group(arg: Object): Aggregate;
+ limit(num: number): Aggregate;
+ match(arg: Object): Aggregate;
+ near(parameters: Object): Aggregate;
+ project(arg: string): Aggregate;
+ project(arg: Object): Aggregate;
+ select(filter: string): Aggregate;
+ skip(num: number): Aggregate;
+ sort(arg: string): Aggregate;
+ sort(arg: Object): Aggregate;
+ unwind(fiels: string, ...rest: string[]): Aggregate;
+
+ exec(callback?: (err: any, result: T) => void): Promise;
+ read(pref: string, ...tags: Object[]): Aggregate;
+ }
+
+ export class Promise {
+ constructor(fn?: (err: any, result: T) => void);
+
+ then(onFulFill: (result: T) => void, onReject?: (err: any) => void): Promise;
+ end(): void;
+
+ fulfill(result: T): Promise;
+ reject(err: any): Promise;
+ resolve(err: any, result: T): Promise;
+
+ onFulfill(listener: (result: T) => void): Promise;
+ onReject(listener: (err: any) => void): Promise;
+ onResolve(listener: (err: any, result: T) => void): Promise;
+ on(event: string, listener: Function): Promise;
+
+ // Deprecated methods.
+ addBack(listener: (err: any, result: T) => void): Promise;
+ addCallback(listener: (result: T) => void): Promise;
+ addErrback(listener: (err: any) => void): Promise;
+ complete(result: T): Promise;
+ error(err: any): Promise;
+ }
+
+}
+