Merge pull request #17841 from overleaf/jel-lint-populate

[web] Add linting rule for mongoose `populate`

GitOrigin-RevId: 625b2b5f9db4e88ce0d629752f083b8be71c7766
This commit is contained in:
Jessica Lawshe 2024-04-11 08:27:17 -05:00 committed by Copybot
parent 11b3c60f60
commit 955c860b64
5 changed files with 23 additions and 5 deletions

View file

@ -93,22 +93,35 @@
// do not allow importing of devDependencies. // do not allow importing of devDependencies.
"devDependencies": false "devDependencies": false
}], }],
// do not allow node-fetch in backend code
"no-restricted-syntax": [ "no-restricted-syntax": [
"error", "error",
// do not allow node-fetch in backend code
{ {
"selector": "CallExpression[callee.name='require'] > .arguments[value='node-fetch']", "selector": "CallExpression[callee.name='require'] > .arguments[value='node-fetch']",
"message": "Requiring node-fetch is not allowed in production services, please use fetch-utils." "message": "Requiring node-fetch is not allowed in production services, please use fetch-utils."
},
// mongoose populate must set fields to populate
{
"selector": "CallExpression[callee.property.name='populate'][arguments.length<2]",
"message": "Populate without a second argument returns the whole document. Use populate('field',['prop1','prop2']) instead"
},
// Require `new` when constructing ObjectId (For mongo + mongoose upgrade)
{
"selector": "CallExpression[callee.name='ObjectId'], CallExpression[callee.property.name='ObjectId']",
"message": "Construct ObjectId with `new ObjectId()` instead of `ObjectId()`"
},
// Require `new` when mapping a list of ids to a list of ObjectId (For mongo + mongoose upgrade)
{
"selector": "CallExpression[callee.property.name='map'] Identifier[name='ObjectId']:first-child, CallExpression[callee.property.name='map'] MemberExpression[property.name='ObjectId']:first-child",
"message": "Don't map ObjectId directly. Use `id => new ObjectId(id)` instead"
} }
] ]
} }
}, },
{ {
// Backend + backend tests specific rules // Backend tests and scripts specific rules
"files": ["**/app/src/**/*.js", "app.js", "**/test/**/*.*", "**/scripts/*.*"], "files": ["**/test/**/*.*", "**/scripts/*.*"],
"rules": { "rules": {
// do not allow node-fetch in backend code
"no-restricted-syntax": [ "no-restricted-syntax": [
"error", "error",
// Require `new` when constructing ObjectId (For mongo + mongoose upgrade) // Require `new` when constructing ObjectId (For mongo + mongoose upgrade)

View file

@ -15,6 +15,7 @@ const CollaboratorsEmailHandler = {
}, },
async notifyUserOfProjectInvite(projectId, email, invite, sendingUser) { async notifyUserOfProjectInvite(projectId, email, invite, sendingUser) {
// eslint-disable-next-line no-restricted-syntax
const project = await Project.findOne({ _id: projectId }) const project = await Project.findOne({ _id: projectId })
.select('name owner_ref') .select('name owner_ref')
.populate('owner_ref') .populate('owner_ref')

View file

@ -23,6 +23,7 @@ const SubscriptionLocator = {
}, },
async getManagedGroupSubscriptions(userOrId) { async getManagedGroupSubscriptions(userOrId) {
// eslint-disable-next-line no-restricted-syntax
return await Subscription.find({ return await Subscription.find({
manager_ids: userOrId, manager_ids: userOrId,
groupPlan: true, groupPlan: true,
@ -33,6 +34,7 @@ const SubscriptionLocator = {
async getMemberSubscriptions(userOrId) { async getMemberSubscriptions(userOrId) {
const userId = SubscriptionLocator._getUserId(userOrId) const userId = SubscriptionLocator._getUserId(userOrId)
// eslint-disable-next-line no-restricted-syntax
return await Subscription.find({ member_ids: userId }) return await Subscription.find({ member_ids: userId })
.populate('admin_id') .populate('admin_id')
.exec() .exec()

View file

@ -90,6 +90,7 @@ async function viewInvite(req, res, next) {
if (subscription?.groupPolicy) { if (subscription?.groupPolicy) {
if (!subscription.populated('groupPolicy')) { if (!subscription.populated('groupPolicy')) {
// eslint-disable-next-line no-restricted-syntax
await subscription.populate('groupPolicy') await subscription.populate('groupPolicy')
} }

View file

@ -46,6 +46,7 @@ class PromisifiedSubscription {
} }
async getWithGroupPolicy() { async getWithGroupPolicy() {
// eslint-disable-next-line no-restricted-syntax
return await SubscriptionModel.findById(this._id) return await SubscriptionModel.findById(this._id)
.populate('groupPolicy') .populate('groupPolicy')
.exec() .exec()