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; + } + +} +