Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check-types with option exemptTagContexts.tag still warns for no-undefined-types #695

Closed

Comments

@thernstig
Copy link

(Note: I am unsure if this should belong to https://github.com/jsdoctypeparser/jsdoctypeparser/issues/ as it is a mix of things happening)

Expected behavior

I would not want to get a warning for The type 'get' is undefined.eslintjsdoc/no-undefined-types for the following parameter:
@api {get} /users/ Get a list of users. I expect to get no warning as I have set jsdoc/check-types and the option exemptTagContexts to exempt api. To me this should mean that it should not care if it is defined or not, as I do not want to check the type.

Actual behavior

I do get a warning.

ESLint Config

{
  "root": true,
  "parserOptions": {
    "ecmaVersion": 2020
  },
  "env": {
    "node": true,
    "es2020": true
  },
  "extends": ["plugin:jsdoc/recommended"],
  "overrides": [
    {
      "files": ["test.js"],
      "rules": {
        "jsdoc/check-tag-names": [
          "warn",
          {
            "definedTags": [
              "api",
              "apiDescription",
              "apiErrorExample",
              "apiGroup",
              "apiName",
              "apiParam",
              "apiHeader",
              "apiParamExample",
              "apiPermission",
              "apiPrivate",
              "apiSuccess",
              "apiSuccessExample"
            ]
          }
        ],
        "jsdoc/check-types": [
          "warn",
          {
            "exemptTagContexts": [
              {
                "tag": "api",
                "types": ["get", "head", "post", "put", "patch", "delete"]
              },
              { "tag": "apiDescription", "types": true },
              { "tag": "apiErrorExample", "types": true },
              { "tag": "apiGroup", "types": true },
              { "tag": "apiName", "types": true },
              { "tag": "apiParam", "types": true },
              { "tag": "apiHeader", "types": true },
              { "tag": "apiParamExample", "types": true },
              { "tag": "apiPermission", "types": true },
              { "tag": "apiPrivate", "types": true },
              { "tag": "apiSuccess", "types": true },
              { "tag": "apiSuccessExample", "types": true }
            ]
          }
        ]
      }
    }
  ]
}

ESLint sample

// test.js

const express = require('express');

const router = express.Router();

/**
 * @api {get} /users/ Get a list of users.
 * @apiGroup Users
 *
 * @apiSuccess {Object} Users - A list of users
 */
router.get('/users', (req, res) => {
  res.status(200).json(['Foo']);
});

module.exports = { router };

Environment

  • Node version: v14.15.1
  • ESLint version v7.19.0
  • eslint-plugin-jsdoc version: 31.6.1
@brettz9
Copy link
Collaborator

brettz9 commented Feb 19, 2021

Rules are almost always interdependent of one another in ESLint (no-unsed-vars can be impacted by the API markVariableAsUsed), and we aim to do the same (even if there a way could be found to get at another rule's options).

A rule's options could be changed into settings, however, which are allowed to be reused across rules, and I'd personally be ok with this if someone wanted to prepare a PR to change this option to a settings-based one.

Note that you can get a variable not to be listed as undefined by adding it to globals (either as an inline comment or as a property in your ESLint config file). But this will require you duplicating the information (and also will mean that a regular undefined variable in code like get() will not be caught).

@thernstig
Copy link
Author

Thanks for the answer @brettz9. You mentioned globals, are you saying that adding post, get etc. as a global is the way to solve this?

I am basically trying to use eslint-plugin-jsdoc to also lint files in a certain location using overrides, to allow for https://apidocjs.com/ to be linted. The only problem left is these get, post etc. types. Since my initial idea above with exemptTagContexts.tag does not work, I was thinking of trying to add them somehow (need to read up on this) as allowed types for the paths I specify in overrides. I am thinking this is the best way to achieve that?

"jsdoc/no-undefined-types": ["error", {"definedTypes":["get", "post", "etc"]}]

Although, a setting as you mention would definitely be the best answer to this as only the tag @api should allow get, post etc.

@brettz9
Copy link
Collaborator

brettz9 commented Feb 20, 2021

I had forgotten you could use definedTypes (as well as globals). Yes, that is even better.

As far as a solution to the redundancy, maybe exemptTagContexts on check-types could be avoided in the future (as well as used by no-undefined-types) by our allowing an array for settings.jsdoc.structuredTags like:

{
  settings: {
    jsdoc: {
      structuredTags: {
        api: {type: ["get", "head", "post", "put", "patch", "delete"]}
      }
    }
  }
}

Given that you only want the types available to tags like api, for your case, you could avoid definedTypes too with such a feature implemented (and avoid the need for definedTags with check-tag-names).

brettz9 added a commit to brettz9/eslint-plugin-jsdoc that referenced this issue Feb 21, 2021
…ay of permissible types, reporting if not present; fixes gajus#695
@thernstig
Copy link
Author

That is definitely a great solution! Would be nice to add custom tags to any custom param like that.

@brettz9
Copy link
Collaborator

brettz9 commented Feb 21, 2021

I've offered a PR for that at #698. It doesn't allow structuredTags to designate a tag as allowing bad types, but it does allow the whitelist. I assume you don't really need bad types within the { and } if you are using types like Object?

@thernstig
Copy link
Author

thernstig commented Feb 21, 2021

I am using types like get, post etc. which really are not types, but allowed within the apiDoc:

/**
 * @api {get} /user/:id Request User information
 * @apiName GetUser
 * @apiGroup User
 *
 * @apiParam {Number} id Users unique ID.
 *
 * @apiSuccess {String} firstname Firstname of the User.
 * @apiSuccess {String} lastname  Lastname of the User.
 */

But that was probably not what you were asking?

@brettz9
Copy link
Collaborator

brettz9 commented Feb 21, 2021

Those are most likely going to be treatable valid types though. If you put "get" in the box at https://jsdoctypeparser.github.io/ , you can see it works. The concern is more with special characters like % unless they are in a position where expected (e.g., = at the end is ok, but not in the middle). I wouldn't expect this would be an issue for you from your description. Also, I think even special characters would work fine if part of the type whitelist.

Btw, I also added a commit to the PR to support treating type arrays' contents as defined for purposes of no-undefined-types

@thernstig
Copy link
Author

Great, then I think I am fine. Using this will be sweet to solve my problem:

{
  settings: {
    jsdoc: {
      structuredTags: {
        api: {type: ["get", "head", "post", "put", "patch", "delete"]}
      }
    }
  }
}

@thernstig
Copy link
Author

As soon as this is merged and released I will test it and reply back here :)

brettz9 added a commit to brettz9/eslint-plugin-jsdoc that referenced this issue Feb 23, 2021
…ay of permissible types, reporting if not present; fixes gajus#695
brettz9 added a commit that referenced this issue Feb 23, 2021
…ay of permissible types, reporting if not present; fixes #695
@gajus
Copy link
Owner

gajus commented Feb 23, 2021

🎉 This issue has been resolved in version 32.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@gajus gajus added the released label Feb 23, 2021
@thernstig
Copy link
Author

@brettz9 worked wonders 💯

This was referenced Mar 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment