UNPKG

eslint-plugin-rxjs

Version:
188 lines (187 loc) 7.2 kB
"use strict"; const eslint_etc_1 = require("eslint-etc"); const utils_1 = require("../utils"); const defaultOptions = []; const rule = (0, utils_1.ruleCreator)({ defaultOptions, meta: { docs: { description: "Enforces the use of a suffix in subject identifiers.", recommended: false, }, fixable: undefined, hasSuggestions: false, messages: { forbidden: `Subject identifiers must end with "{{suffix}}".`, }, schema: [ { properties: { parameters: { type: "boolean" }, properties: { type: "boolean" }, suffix: { type: "string" }, types: { type: "object" }, variables: { type: "boolean" }, }, type: "object", }, ], type: "problem", }, name: "suffix-subjects", create: (context, unused) => { const { esTreeNodeToTSNodeMap } = (0, eslint_etc_1.getParserServices)(context); const { couldBeType } = (0, eslint_etc_1.getTypeServices)(context); const [config = {}] = context.options; const validate = { parameters: true, properties: true, variables: true, ...config, }; const types = []; if (config.types) { Object.entries(config.types).forEach(([key, validate]) => { types.push({ regExp: new RegExp(key), validate }); }); } else { types.push({ regExp: /^EventEmitter$/, validate: false, }); } const { suffix = "Subject" } = config; const suffixRegex = new RegExp(String.raw `${(0, utils_1.escapeRegExp)(suffix)}\$?$`, "i"); function checkNode(nameNode, typeNode) { let tsNode = esTreeNodeToTSNodeMap.get(nameNode); const text = tsNode.getText(); if (!suffixRegex.test(text) && couldBeType(typeNode || nameNode, "Subject")) { for (const type of types) { const { regExp, validate } = type; if (couldBeType(typeNode || nameNode, regExp) && !validate) { return; } } context.report({ data: { suffix }, loc: (0, eslint_etc_1.getLoc)(tsNode), messageId: "forbidden", }); } } return { "ArrayPattern > Identifier": (node) => { const found = (0, eslint_etc_1.findParent)(node, "ArrowFunctionExpression", "FunctionDeclaration", "FunctionExpression", "VariableDeclarator"); if (!found) { return; } if (!validate.variables && found.type === "VariableDeclarator") { return; } if (!validate.parameters) { return; } checkNode(node); }, "ArrowFunctionExpression > Identifier": (node) => { if (validate.parameters) { const parent = (0, eslint_etc_1.getParent)(node); if (node !== parent.body) { checkNode(node); } } }, "PropertyDefinition[computed=false]": (node) => { const anyNode = node; if (validate.properties) { checkNode(anyNode.key); } }, "FunctionDeclaration > Identifier": (node) => { if (validate.parameters) { const parent = (0, eslint_etc_1.getParent)(node); if (node !== parent.id) { checkNode(node); } } }, "FunctionExpression > Identifier": (node) => { if (validate.parameters) { const parent = (0, eslint_etc_1.getParent)(node); if (node !== parent.id) { checkNode(node); } } }, "MethodDefinition[kind='get'][computed=false]": (node) => { if (validate.properties) { checkNode(node.key, node); } }, "MethodDefinition[kind='set'][computed=false]": (node) => { if (validate.properties) { checkNode(node.key, node); } }, "ObjectExpression > Property[computed=false] > Identifier": (node) => { if (validate.properties) { const parent = (0, eslint_etc_1.getParent)(node); if (node === parent.key) { checkNode(node); } } }, "ObjectPattern > Property > Identifier": (node) => { const found = (0, eslint_etc_1.findParent)(node, "ArrowFunctionExpression", "FunctionDeclaration", "FunctionExpression", "VariableDeclarator"); if (!found) { return; } if (!validate.variables && found.type === "VariableDeclarator") { return; } if (!validate.parameters) { return; } const parent = (0, eslint_etc_1.getParent)(node); if (node === parent.value) { checkNode(node); } }, "TSCallSignatureDeclaration > Identifier": (node) => { if (validate.parameters) { checkNode(node); } }, "TSConstructSignatureDeclaration > Identifier": (node) => { if (validate.parameters) { checkNode(node); } }, "TSMethodSignature > Identifier": (node) => { if (validate.parameters) { checkNode(node); } }, "TSParameterProperty > Identifier": (node) => { if (validate.parameters || validate.properties) { checkNode(node); } }, "TSPropertySignature[computed=false]": (node) => { const anyNode = node; if (validate.properties) { checkNode(anyNode.key); } }, "VariableDeclarator > Identifier": (node) => { const parent = (0, eslint_etc_1.getParent)(node); if (validate.variables && node === parent.id) { checkNode(node); } }, }; }, }); module.exports = rule;