-
-
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: