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)

Most upvoted comments

I opened an issue at mongoose https://github.com/Automattic/mongoose/issues/12286

As a workaround you can use any findOne*method since findById is just an alias.

find().findByIdAndDelete() is not found but find().findOneAndDelete() is. I would advice not using these findById shorthands as they often create problems.

@danielbayerlein do you have suggestion how to fix this?

Because this is how mongoose types designed, for example find explicitly returns an array of items without not carrying what was the return type of prev query. The same with findOne and co. That’s why accessibleBy returns an array because then it’s easy to convert to single record using findOne.

Want many use Post.accessibleBy(...) want one use Post.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 findById but this question should be addressed to mongoose.Query typings