UNPKG

lwc-linter

Version:

A comprehensive CLI tool for linting Lightning Web Components v8.0.0+ with modern LWC patterns, decorators, lifecycle hooks, and Salesforce platform integration

161 lines 6.52 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.FileProcessor = void 0; const acorn = __importStar(require("acorn")); const htmlparser2_1 = require("htmlparser2"); const rule_manager_1 = require("./rule-manager"); class FileProcessor { constructor(config) { this.config = config; this.ruleManager = new rule_manager_1.RuleManager(config); } async processJavaScript(content, filePath) { const issues = []; try { // Preprocess LWC decorators for better parsing compatibility const cleanedContent = this.preprocessLWCDecorators(content); // Parse JavaScript with Acorn const ast = acorn.parse(cleanedContent, { ecmaVersion: 2022, sourceType: 'module', locations: true, allowHashBang: true, allowReturnOutsideFunction: true }); // Apply JavaScript-specific rules issues.push(...this.ruleManager.checkJavaScriptRules(content, filePath, ast)); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); // Filter out LWC decorator-related syntax errors if (this.isLWCDecoratorError(errorMessage)) { // Skip this error - it's just LWC decorators which are valid console.log(`ℹ️ Skipping LWC decorator syntax in ${filePath}`); } else { issues.push({ rule: 'syntax-error', message: `JavaScript syntax error: ${errorMessage}`, severity: 'error', category: 'code-quality' }); } } return issues; } preprocessLWCDecorators(content) { // Remove LWC v8.0.0+ decorators to make the code parseable by standard JavaScript parser let cleanedContent = content // Core LWC decorators .replace(/@api\s+/g, '/* @api */ ') .replace(/@track\s+/g, '/* @track */ ') .replace(/@wire\s*\([^)]*\)\s*/g, '/* @wire(...) */ ') // Enhanced LWC v8.0.0+ decorators .replace(/@consume\s*\([^)]*\)\s*/g, '/* @consume(...) */ ') .replace(/@provide\s*\([^)]*\)\s*/g, '/* @provide(...) */ ') .replace(/@reactive\s+/g, '/* @reactive */ ') // Salesforce platform decorators .replace(/@salesforceUx\s*(\([^)]*\))?\s*/g, '/* @salesforceUx$1 */ ') .replace(/@namespace\s*(\([^)]*\))?\s*/g, '/* @namespace$1 */ ') // Developer-defined custom decorators (common patterns) .replace(/@([a-zA-Z][a-zA-Z0-9]*)\s*(\([^)]*\))?\s*/g, '/* @$1$2 */ '); return cleanedContent; } isLWCDecoratorError(errorMessage) { // Check if the error is related to LWC v8.0.0+ decorators const lwcDecoratorPatterns = [ /Unexpected character '@'/, /Unexpected token '@'/, /@api/, /@track/, /@wire/, /@consume/, /@provide/, /@reactive/, /@salesforceUx/, /@namespace/, /Invalid left-hand side in assignment/, /Unexpected token, expected/, /Decorators are not valid here/, /Unexpected decorator/ ]; return lwcDecoratorPatterns.some(pattern => pattern.test(errorMessage)); } async processHTML(content, filePath) { const issues = []; try { // Parse HTML with htmlparser2 const document = (0, htmlparser2_1.parseDocument)(content, { withStartIndices: true, withEndIndices: true }); // Apply HTML-specific rules issues.push(...this.ruleManager.checkHTMLRules(content, filePath, document)); // Apply accessibility rules if (this.config.accessibility?.enabled) { issues.push(...this.ruleManager.checkAccessibilityRules(content, filePath, document)); } } catch (error) { issues.push({ rule: 'syntax-error', message: `HTML parsing error: ${error instanceof Error ? error.message : error}`, severity: 'error', category: 'code-quality' }); } return issues; } async processCSS(content, filePath) { const issues = []; try { // Simple CSS processing without css-tree // Apply CSS-specific rules issues.push(...this.ruleManager.checkCSSRules(content, filePath, null)); } catch (error) { issues.push({ rule: 'syntax-error', message: `CSS parsing error: ${error instanceof Error ? error.message : error}`, severity: 'error', category: 'code-quality' }); } return issues; } } exports.FileProcessor = FileProcessor; //# sourceMappingURL=file-processor.js.map