UNPKG

@addon24/eslint-config

Version:

ESLint configuration rules for WorldOfTextcraft projects - Centralized configuration for all project types

152 lines (140 loc) 5.83 kB
export default { meta: { type: "problem", docs: { description: "Forbid direct usage of import.meta.env, use ConfigProvider instead", category: "Best Practices", recommended: true, }, fixable: "code", schema: [], messages: { noImportMetaEnv: "Direct usage of import.meta.env is forbidden. Use ConfigProvider methods instead to ensure proper validation and error handling.", }, }, create (context) { let hasConfigProviderImport = false; return { ImportDeclaration (node) { // Check if ConfigProvider is already imported if (node.source.value.includes("ConfigProvider")) { hasConfigProviderImport = true; } }, MemberExpression (node) { if ( node.object && node.object.type === "MetaProperty" && node.object.meta && node.object.meta.name === "import" && node.object.property && node.object.property.name === "meta" && node.property && node.property.name === "env" ) { context.report({ node, messageId: "noImportMetaEnv", fix (fixer) { const fixes = []; // Add ConfigProvider import if not present if (!hasConfigProviderImport) { const program = context.getSourceCode().ast; const lastImport = program.body.filter(n => n.type === "ImportDeclaration").slice(-1)[0] || null; if (lastImport) { fixes.push( fixer.insertTextAfter( lastImport, '\nimport { ConfigProvider } from "@/config/ConfigProvider";' ) ); } else { fixes.push( fixer.insertTextBeforeRange([0, 0], 'import { ConfigProvider } from "@/config/ConfigProvider";\n') ); } } // Check if this is accessing a specific environment variable const parent = node.parent; if (parent && parent.type === "MemberExpression" && parent.property) { const rawName = parent.property.name || parent.property.value; const toCamel = (name) => { const lower = String(name).toLowerCase(); if (lower === "node_env") return "NodeEnv"; if (lower === "db_host") return "DbHost"; if (lower === "db_port") return "DbPort"; if (lower === "db_timeout") return "DbTimeout"; if (lower === "database_url" || lower === "db_url") return "DatabaseUrl"; if (lower === "log_level") return "LogLevel"; if (lower === "api_url") return "ApiUrl"; if (lower === "secret_key") return "SecretKey"; if (lower === "primary_db_url") return "PrimaryDbUrl"; if (lower === "replica_db_url") return "ReplicaDbUrl"; if (lower === "redis_url") return "RedisUrl"; if (lower === "redis_ttl") return "RedisTtl"; const parts = String(name).split(/[_-]+/); return parts.map((p, i) => i === 0 ? p.charAt(0).toUpperCase() + p.slice(1).toLowerCase() : p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()).join(""); }; const envVarName = toCamel(rawName); if (envVarName) { // Convert to ConfigProvider method call const methodName = `get${envVarName}`; fixes.push(fixer.replaceText(parent, `ConfigProvider.${methodName}()`)); } else { // Fallback: replace with generic ConfigProvider call fixes.push(fixer.replaceText(node, "ConfigProvider")); } } else { // Replace the entire import.meta.env with ConfigProvider fixes.push(fixer.replaceText(node, "ConfigProvider")); } return fixes; }, }); } }, CallExpression (node) { if ( node.callee && node.callee.type === "MemberExpression" && node.callee.object && node.callee.object.type === "MetaProperty" && node.callee.object.meta && node.callee.object.meta.name === "import" && node.callee.object.property && node.callee.object.property.name === "meta" && node.callee.property && node.callee.property.name === "env" ) { context.report({ node, messageId: "noImportMetaEnv", fix (fixer) { const fixes = []; // Add ConfigProvider import if not present if (!hasConfigProviderImport) { const program = context.getSourceCode().ast; const lastImport = program.body.filter(n => n.type === "ImportDeclaration").slice(-1)[0] || null; if (lastImport) { fixes.push( fixer.insertTextAfter( lastImport, '\nimport { ConfigProvider } from "@/config/ConfigProvider";' ) ); } else { fixes.push( fixer.insertTextBeforeRange([0, 0], 'import { ConfigProvider } from "@/config/ConfigProvider";\n') ); } } // Replace the call with ConfigProvider fixes.push(fixer.replaceText(node.callee, "ConfigProvider")); return fixes; }, }); } }, }; }, };