From 5ed0b6507603f37bab7bfef280c6d7ffa372c711 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 21 Aug 2016 22:24:13 -0400 Subject: [PATCH] adds a README plus better tests --- mongoose/README.md | 192 +++++++++++++++++- mongoose/mongoose-tests.ts | 8 +- mongoose/mongoose.d.ts | 15 +- .../passport-local-mongoose-tests.ts | 2 +- 4 files changed, 212 insertions(+), 5 deletions(-) diff --git a/mongoose/README.md b/mongoose/README.md index 4a581dcfdb..03b483ecd1 100644 --- a/mongoose/README.md +++ b/mongoose/README.md @@ -1 +1,191 @@ -# TESTING \ No newline at end of file +## MongooseJS Typescript Docs +Below are some examples of how to use these Definitions.
+Scenarios where the Typescript code is identical to plain Javascript code are omitted. + +#### Mongoose Methods, Properties, Constructors +You can call methods from the mongoose instance using: +``` +import * as mongoose from 'mongoose'; +var MyModel = mongoose.model(...); +var MySchema: mongoose.Schema = new mongoose.Schema(...); +``` + +Alternatively, you can import individual names and call them: +``` +import {model, Schema} from 'mongoose'; +var MyModel = model(...); +var MySchema: Schema = new Schema(...): +``` + + +#### Creating and Saving Documents +``` +import {Document, model, Model, Schema} from 'mongoose'; + +var UserSchema: Schema = new Schema({ + username: { + type: String, + required: true, + unique: true + }, + age: Number, + friends: [String], + data: [Schema.Types.Mixed] +}); + +interface IUser extends Document { + username: string; + age: number; + friends: string[]; + data: any[]; +} + +var UserModel: Model = mongoose.model('User', UserSchema); + +var user = new UserModel({name: 'Jane'}); +user.username; // IUser properties are available +user.save(); // mongoose Document methods are available + +UserModel.findOne({}, (err: any, user: IUser) => { + user.username; // IUser properties are available + user.save(); // mongoose Document methods are available +}); +``` + +#### Instance Methods and Virtual Properties +``` +import {Document, model, Model, Schema} from 'mongoose'; + +var UserSchema: Schema = new Schema({ + name: String +}); + +UserSchema.methods.method1 = function () { return '' }; +UserSchema.virtual('nameInCaps').get(function () { + return this.name.toUpperCase(); +}); +UserSchema.virtual('nameInCaps').set(function (caps) { + this.name = caps.toLowerCase(); +}); + +interface IUser extends Document { + name: string; + nameInCaps: string; + method1: () => string; +} + +var UserModel: Model = model('User', UserSchema); +var user = new UserModel({name: 'Billy'}); + +user.method1(); // IUser methods are available +user.nameInCaps; // virtual properties can be used + +UserModel.findOne({}, (err: any, user: IUser) => { + user.method1(); // IUser methods are available + user.nameInCaps; // virtual properties can be used +}); +``` + +#### Static Methods +``` +import {Document, model, Model, Schema} from 'mongoose'; + +var UserSchema = new Schema({}); +UserSchema.statics.static1 = function () { return '' }; + +interface IUserDocument extends Document {...} +interface IUserModel extends Model { + static1: () => string; +} + +var UserModel: IUserModel = model('User', UserSchema); +UserModel.static1(); // static methods are available +``` + +#### Plugins +To write definitions for plugins, extend the mongoose module and create a simple plugin module: +``` +// plugin.d.ts +declare module 'mongoose' { + export interface PassportLocalDocument {...} + export interface PassportLocalSchema extends Schema {...} + export interface PassportLocalModel extends Model {...} + ... +} + +declare module 'passport-local-mongoose' { + import mongoose = require('mongoose'); + var _: (schema: mongoose.Schema, options?: Object) => void; + export = _; +} + +// user.ts +import { + model, + PassportLocalDocument, + PassportLocalSchema, + PassportLocalModel + Schema +} from 'mongoose'; +import * as passportLocalMongoose from 'passport-local-mongoose'; + +var UserSchema: PassportLocalSchema = new Schema({}); +UserSchema.plugin(passportLocalMongoose, options); + +interface IUser extends PassportLocalDocument {...} +interface IUserModel extends PassportLocalModel {...} + +var UserModel: IUserModel = model('User', UserSchema); +``` +Full example for [Passport Local Mongoose](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/passport-local-mongoose/passport-local-mongoose.d.ts) + +#### Promises +These definitions use global.Promise by default. If you would like to use mongoose's own mpromise +definition (which is deprecated), you can install definitions for [mongoose-promise](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/mongoose-promise). + +If you'd like to use something other than global.Promise, you'll need to create a simple .d.ts file: +``` +// promise-bluebird.d.ts +import * as Bluebird from 'bluebird'; + +declare module 'mongoose' { + type Promise = Bluebird; +} + +// promise-q.d.ts +import * as Q from 'q'; + +declare module 'mongoose' { + type Promise = Q.Promise; +} + +// another-promise.d.ts +... +``` +To use it, you will need to `/// ` in one of your source code files, +or include the `.d.ts` file in your compile. + +To assign the new promise library in your code, you will need to use one of the following options (since +Typescript does not allow assigning properties of imported modules): + +* `(mongoose).Promise = YOUR_PROMISE;` +* `require('mongoose').Promise = YOUR_PROMISE;` +* `import mongoose = require('mongoose'); ... mongoose.Promise = YOUR_PROMISE;` + +#### FAQ +Q: Why are there 2 interfaces for Documents called Document and MongooseDocument?
+A: People have been using this for a long time: +``` +interface IUser extends mongoose.Document { + ... +} +``` +When it should really be this: +``` +interface IUser extends mongoose.model { + ... +} +``` +For backwards compatibility Document is an interface for [mongoose.model](https://github.com/Automattic/mongoose/blob/master/lib/model.js#L3162)
+And MongooseDocument is an interface for [mongoose.Document](https://github.com/Automattic/mongoose/blob/master/lib/model.js#L3162)
+At some point in the future this may get fixed, which would require fixing your code. \ No newline at end of file diff --git a/mongoose/mongoose-tests.ts b/mongoose/mongoose-tests.ts index d846023143..51959b9e41 100644 --- a/mongoose/mongoose-tests.ts +++ b/mongoose/mongoose-tests.ts @@ -1379,4 +1379,10 @@ Final.findOne(function (err: any, doc: MyDocument) { doc.save(); doc.remove(); doc.model(''); -}); \ No newline at end of file +}); +export var Final2: MyModel = mongoose.model('Final2', mySchema); +Final2.staticMethod(); +Final2.staticProp; +var final2 = new Final2(); +final2.prop; +final2.method; \ No newline at end of file diff --git a/mongoose/mongoose.d.ts b/mongoose/mongoose.d.ts index b28a222778..81247104ef 100644 --- a/mongoose/mongoose.d.ts +++ b/mongoose/mongoose.d.ts @@ -152,6 +152,12 @@ declare module "mongoose" { */ export function model(name: string, schema?: Schema, collection?: string, skipInit?: boolean): Model; + export function model>( + name: string, + schema?: Schema, + collection?: string, + skipInit?: boolean + ): U; /** * Returns an array of model names created on this instance of Mongoose. @@ -311,6 +317,11 @@ declare module "mongoose" { * @returns The compiled model */ model(name: string, schema?: Schema, collection?: string): Model; + model>( + name: string, + schema?: Schema, + collection?: string + ): U; /** Returns an array of model names created on this connection. */ modelNames(): string[]; @@ -704,7 +715,7 @@ declare module "mongoose" { * section document.js * http://mongoosejs.com/docs/api.html#document-js */ - class MongooseDocument { + interface MongooseDocument { /** Checks if a path is set to its default. */ $isDefault(path?: string): boolean; @@ -2074,7 +2085,7 @@ declare module "mongoose" { findById(id: Object | string | number, projection: Object, options: Object, callback?: (err: any, res: T) => void): DocumentQuery; - model(name: string): Model; + model(name: string): Model; /** * Creates a Query and specifies a $where condition. diff --git a/passport-local-mongoose/passport-local-mongoose-tests.ts b/passport-local-mongoose/passport-local-mongoose-tests.ts index 993d5b05da..c7d4ffc381 100644 --- a/passport-local-mongoose/passport-local-mongoose-tests.ts +++ b/passport-local-mongoose/passport-local-mongoose-tests.ts @@ -34,7 +34,7 @@ interface User extends PassportLocalDocument { last: Date; } -const UserSchema: PassportLocalSchema = new Schema({ +const UserSchema: PassportLocalSchema = new Schema({ username: String, hash: String, salt: String,