UNPKG

eslint-plugin-lit

Version:
80 lines (79 loc) 3.45 kB
/** * @fileoverview Disallows usages of "non-public" property bindings * @author Michael Stramel <https://github.com/stramel> */ import { TemplateAnalyzer } from '../template-analyzer.js'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ export const rule = { meta: { docs: { description: 'Disallows usages of "non-public" property bindings', recommended: false, url: 'https://github.com/43081j/eslint-plugin-lit/blob/master/docs/rules/no-private-properties.md' }, schema: [ { type: 'object', properties: { private: { type: 'string', minLength: 1, format: 'regex' }, protected: { type: 'string', minLength: 1, format: 'regex' } }, additionalProperties: false, minProperties: 1 } ], messages: { noPrivate: 'Private and protected properties should not be assigned in bindings' } }, create(context) { const source = context.getSourceCode(); const config = context.options[0] || {}; const conventions = Object.entries(config).reduce((acc, [key, value]) => { if (value) { acc[key] = new RegExp(value); } return acc; }, {}); const conventionRegexes = Object.values(conventions); //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { TaggedTemplateExpression: (node) => { if (node.type === 'TaggedTemplateExpression' && node.tag.type === 'Identifier' && node.tag.name === 'html') { const analyzer = TemplateAnalyzer.create(node); analyzer.traverse({ enterElement: (element) => { // eslint-disable-next-line guard-for-in for (const attr in element.attribs) { const loc = analyzer.getLocationForAttribute(element, attr, source); if (!loc) { continue; } const hasPropertyBinding = '.' === attr.slice(0, 1); if (!hasPropertyBinding) { continue; } const invalidPropertyName = conventionRegexes.some((convention) => convention.test(attr.slice(1))); if (invalidPropertyName) { context.report({ loc, messageId: 'noPrivate' }); } } } }); } } }; } };