]> git.proxmox.com Git - pve-eslint.git/blob - eslint/tools/internal-rules/no-invalid-meta.js
import 8.23.1 source
[pve-eslint.git] / eslint / tools / internal-rules / no-invalid-meta.js
1 /**
2 * @fileoverview Internal rule to prevent missing or invalid meta property in core rules.
3 * @author Vitor Balocco
4 */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Helpers
10 //------------------------------------------------------------------------------
11
12 /**
13 * Gets the property of the Object node passed in that has the name specified.
14 * @param {string} property Name of the property to return.
15 * @param {ASTNode} node The ObjectExpression node.
16 * @returns {ASTNode} The Property node or null if not found.
17 */
18 function getPropertyFromObject(property, node) {
19 const properties = node.properties;
20
21 if (!Array.isArray(properties)) {
22
23 return null;
24 }
25
26 for (let i = 0; i < properties.length; i++) {
27 if (properties[i].key.name === property) {
28 return properties[i];
29 }
30 }
31
32 return null;
33 }
34
35 /**
36 * Extracts the `meta` property from the ObjectExpression that all rules export.
37 * @param {ASTNode} exportsNode ObjectExpression node that the rule exports.
38 * @returns {ASTNode} The `meta` Property node or null if not found.
39 */
40 function getMetaPropertyFromExportsNode(exportsNode) {
41 return getPropertyFromObject("meta", exportsNode);
42 }
43
44 /**
45 * Whether this `meta` ObjectExpression has a `docs` property defined or not.
46 * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule.
47 * @returns {boolean} `true` if a `docs` property exists.
48 */
49 function hasMetaDocs(metaPropertyNode) {
50 return Boolean(getPropertyFromObject("docs", metaPropertyNode.value));
51 }
52
53 /**
54 * Whether this `meta` ObjectExpression has a `docs.recommended` property defined or not.
55 * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule.
56 * @returns {boolean} `true` if a `docs.recommended` property exists.
57 */
58 function hasMetaDocsRecommended(metaPropertyNode) {
59 const metaDocs = getPropertyFromObject("docs", metaPropertyNode.value);
60
61 return metaDocs && getPropertyFromObject("recommended", metaDocs.value);
62 }
63
64 /**
65 * Checks the validity of the meta definition of this rule and reports any errors found.
66 * @param {RuleContext} context The ESLint rule context.
67 * @param {ASTNode} exportsNode ObjectExpression node that the rule exports.
68 * @returns {void}
69 */
70 function checkMetaValidity(context, exportsNode) {
71 const metaProperty = getMetaPropertyFromExportsNode(exportsNode);
72
73 if (!metaProperty) {
74 context.report({ node: exportsNode, messageId: "missingMeta" });
75 return;
76 }
77
78 if (!hasMetaDocs(metaProperty)) {
79 context.report({ node: metaProperty, messageId: "missingMetaDocs" });
80 return;
81 }
82
83 if (!hasMetaDocsRecommended(metaProperty)) {
84 context.report({ node: metaProperty, messageId: "missingMetaDocsRecommended" });
85 }
86 }
87
88 //------------------------------------------------------------------------------
89 // Rule Definition
90 //------------------------------------------------------------------------------
91
92 module.exports = {
93 meta: {
94 docs: {
95 description: "Enforce correct use of `meta` property in core rules",
96 recommended: false
97 },
98 type: "problem",
99 schema: [],
100 messages: {
101 missingMeta: "Rule is missing a meta property.",
102 missingMetaDocs: "Rule is missing a meta.docs property.",
103 missingMetaDocsRecommended: "Rule is missing a meta.docs.recommended property.",
104 noExport: "Rule does not export anything. Make sure rule exports an object according to new rule format."
105 }
106 },
107
108 create(context) {
109 let exportsNode;
110
111 return {
112 AssignmentExpression(node) {
113 if (node.left &&
114 node.right &&
115 node.left.type === "MemberExpression" &&
116 node.left.object.name === "module" &&
117 node.left.property.name === "exports") {
118
119 exportsNode = node.right;
120 }
121 },
122
123 "Program:exit"(node) {
124 if (!exportsNode) {
125 context.report({
126 node,
127 messageId: "noExport"
128 });
129 } else {
130 checkMetaValidity(context, exportsNode);
131 }
132 }
133 };
134 }
135 };