casl: Mongoose type "accessibleBy" returns an array of document after findOne
Model.accessibleBy from @casl/mongoose returns an array of document which makes it hard to deal with with operations such as findById and following:
type CatDocument = Cat & Document
getById(id: MongooseTypes.ObjectId, ability: Ability): Promise<CatDocument>
return this.catModel
.findById(id)
.accessibleBy(ability, Action.Read)
// function return type now needs to be Promise<CatDocument[]>
.exec()
}
Update operations after find one (is there a better way to check ability before update?) trigger an error since it expects an array:
async update(payload: UpdateCatInput, ability: Ability) {
const doc = await this.catModel
.findById(payload.id)
.accessibleBy(ability, Action.Update)
.exec()
if (doc) return doc.set(payload).save()
// Error : Property 'set' does not exist on type '(Cat & Document<any, any, any> & { _id: ObjectId; })[]'
}
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 21 (8 by maintainers)
I opened an issue at mongoose https://github.com/Automattic/mongoose/issues/12286
As a workaround you can use any
findOne*method sincefindByIdis just an alias.find().findByIdAndDelete()is not found butfind().findOneAndDelete()is. I would advice not using thesefindByIdshorthands as they often create problems.@danielbayerlein do you have suggestion how to fix this?
Because this is how mongoose types designed, for example
findexplicitly returns an array of items without not carrying what was the return type of prev query. The same withfindOneand co. That’s whyaccessibleByreturns an array because then it’s easy to convert to single record usingfindOne.Want many use
Post.accessibleBy(...)want one usePost.accessibleBy(...).findOne({ _id: ... }).If you know how to make types work, so that they can rely on prev constructs, then awesome, let’s fix this because I think it’s impossible in how mongoose currently defines its types
FYI this has been fixed in mongoose https://github.com/Automattic/mongoose/pull/12309
Ah OK, there is no
findByIdbut this question should be addressed tomongoose.Querytypings