Преглед изворни кода

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

[web] Add linting rule for mongoose `populate`

GitOrigin-RevId: 625b2b5f9db4e88ce0d629752f083b8be71c7766
Jessica Lawshe пре 2 година
родитељ
комит
955c860b64

+ 18 - 5
services/web/.eslintrc

@@ -93,22 +93,35 @@
           // do not allow importing of devDependencies.
           "devDependencies": false
         }],
-
-        // do not allow node-fetch in backend code
         "no-restricted-syntax": [
           "error",
+          // do not allow node-fetch in backend code
           {
             "selector": "CallExpression[callee.name='require'] > .arguments[value='node-fetch']",
             "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
-      "files": ["**/app/src/**/*.js", "app.js", "**/test/**/*.*", "**/scripts/*.*"],
+      // Backend tests and scripts specific rules
+      "files": ["**/test/**/*.*", "**/scripts/*.*"],
       "rules": {
-        // do not allow node-fetch in backend code
         "no-restricted-syntax": [
           "error",
           // Require `new` when constructing ObjectId (For mongo + mongoose upgrade)

+ 1 - 0
services/web/app/src/Features/Collaborators/CollaboratorsEmailHandler.js

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

+ 2 - 0
services/web/app/src/Features/Subscription/SubscriptionLocator.js

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

+ 1 - 0
services/web/app/src/Features/Subscription/TeamInvitesController.js

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

+ 1 - 0
services/web/test/acceptance/src/helpers/Subscription.js

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