-
-
Save masahirompp/3c012c8721b70821fa45 to your computer and use it in GitHub Desktop.
/// <reference path="../tsd/tsd.d.ts" /> | |
import mongoose = require('mongoose'); | |
import passport = require('passport'); | |
interface IUser extends mongoose.Document { | |
provider: string; | |
id: string; | |
authorId: string; | |
displayName: string; | |
emails: any; | |
photos: any; | |
show: boolean; | |
created: Date; | |
updated: Date; | |
} | |
/** | |
* MongooseSchema | |
* @type {"mongoose".Schema} | |
* @private | |
*/ | |
var _schema: mongoose.Schema = new mongoose.Schema({ | |
provider: { | |
type: String, | |
require: true | |
}, | |
id: { | |
type: String, | |
require: true | |
}, | |
authorId: { | |
type: mongoose.Schema.Types.ObjectId, | |
ref: 'Author' | |
}, | |
displayName: { | |
type: String | |
}, | |
emails: { | |
type: mongoose.Schema.Types.Mixed | |
}, | |
photos: { | |
type: mongoose.Schema.Types.Mixed | |
}, | |
show: Boolean, | |
created: { | |
type: Date, | |
default: Date.now | |
}, | |
updated: { | |
type: Date, | |
default: Date.now | |
} | |
}) | |
.pre('save', function(next) { | |
this.updated = new Date(); | |
next(); | |
}); | |
/** | |
* Mongoose.Model | |
* @type {Model<IUser>} | |
* @private | |
*/ | |
var _model = mongoose.model < IUser > ('User', _schema); | |
class User { | |
/** | |
* static ユーザが存在しなければ作成して返す。 | |
* @param passport.Profile | |
* @returns {Promise<User>} | |
*/ | |
static findOrCreate(profile: passport.Profile): Promise < User > { | |
return new Promise < IUser > ((resolve, reject) => { | |
_model.findOne({ | |
provider: profile.provider, | |
id: profile.id | |
}) | |
.exec() | |
.then(user => { | |
if (user) { | |
return resolve(new User(user)); | |
} | |
_model.create({ | |
provider: profile.provider, | |
id: profile.id, | |
displayName: profile.displayName, | |
emails: profile.emails, | |
photos: profile.photos | |
}) | |
.onResolve((err, user) => { | |
err ? reject(err) : resolve(new User(user)); | |
}); | |
}); | |
}); | |
} | |
/** | |
* static idからUserオブジェクトを取得 | |
* @param id | |
* @returns {Promise<User>} | |
*/ | |
static findById(id: string): Promise < User > { | |
return new Promise < IUser > ((resolve, reject) => { | |
_model.findById(id) | |
.exec() | |
.onResolve((err, user) => { | |
err ? reject(err) : resolve(new User(user)); | |
}); | |
}) | |
} | |
/** | |
* インスタンス変数 | |
*/ | |
private _document: IUser; | |
/** | |
* コンストラクタ | |
* @param mongoose.Document<IUser> | |
*/ | |
constructor(document: IUser) { | |
this._document = document; | |
} | |
get provider(): string { | |
return this._document.provider; | |
} | |
get image(): string { | |
if (Array.isArray(this._document.photos)) { | |
return this._document.photos.length > 0 ? this._document.photos[0] : null; | |
} | |
return this._document.photos; | |
} | |
get show(): boolean { | |
return this._document.show; | |
} | |
get authorId(): string { | |
return this._document.authorId; | |
} | |
} | |
export = User; |
@DNRN Yeah, I have been thinking the same thing, because this snippet sort of makes the mongoose methods and statics obsolete, right?
_schema.methods.methodName = function (*) {
your code
}
Would not work?
Compiling gives me this
src/models/UserModel.ts(4,41): error TS2339: Property 'Document' does not exist on type 'typeof 'mongoose''.
src/models/UserModel.ts(65,37): error TS2344: Type 'UserModel' does not satisfy the constraint 'Document'.
@DNRN & @xChrisPx, did you guys make this work? I'm having the exact same problem with a password comparisson method. "Property 'compare' does not exist on type 'IUser[]'."
Hi, has anybody found a solution to this password comparison method? I'm stuck with the same problem.
Thank you for the sample code. I would like to extend on your solution.
If you extend your User class to _model, it would give you access to all default model functions such as findById, findOne, etc.
Lines 65 and 67
var _model = mongoose.model < IUser > ('User', _schema);
class User <-------------- change this to class User extends _model
and now you can reference 'this' instead of using _model, and you would have all the features in model in your User class.
Thank you, this code helped me a lot.
Edit: just make sure all your static methods names don't try to override the default model methods or you will get a weird large error.
First I like your model, but I have a question. How would you implement methods on the schema?
I have have a validate password method:
Do you know how I could call this from a static validatePassword(password: string) on the class object? The problem is TypeScript is not aware of this "validatePassword" method?
Or is the easiest way to collect it all in one function: