UNPKG

eslint-plugin-export-scope

Version:

Don't leak LOCAL utils, states, components into the global scope

100 lines 4.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateProgram = void 0; const scope_manager_1 = require("@typescript-eslint/scope-manager"); const utils_1 = require("@typescript-eslint/utils"); const validateJsDoc_1 = require("./validateJsDoc"); const esLintUtils_1 = require("./esLintUtils"); const validateProgram = (context, node, lintNode) => { (0, validateJsDoc_1.validateJsDoc)(context, node); const getModuleNames = (rootVariable, variables) => { const moduleNames = new Set([rootVariable.name]); const variableNameToVariableMap = new Map(variables.map((variable) => [variable.name, variable])); const iterateRefs = (variable) => { variable.references.forEach((ref) => { const decl = ref.identifier.parent; if (decl.type === utils_1.AST_NODE_TYPES.VariableDeclarator && decl.id.type === utils_1.AST_NODE_TYPES.Identifier) { const isAlreadyAdded = moduleNames.has(decl.id.name); moduleNames.add(decl.id.name); if (!isAlreadyAdded) { const variable = variableNameToVariableMap.get(decl.id.name); if (variable) iterateRefs(variable); } } }); }; iterateRefs(rootVariable); return moduleNames; }; let scopeTree; try { scopeTree = (0, scope_manager_1.analyze)(node, { sourceType: "module" }); } catch { console.error("🚨 Please upgrade all @typescript-eslint/* packages to the latest mojor version 🚨"); return; } const globalVariables = scopeTree.globalScope?.childScopes[0]?.variables; if (!globalVariables) return; const lintVariable = (variable, scopeVariables, relExportPath) => { const variableNameToVariableMap = new Map(scopeVariables.map((variable) => [variable.name, variable])); const moduleNames = getModuleNames(variable, scopeVariables); const variables = Array.from(moduleNames) .map((name) => variableNameToVariableMap.get(name)) .filter(Boolean); variables.forEach((variable) => variable.references.forEach((ref) => lintNode(ref.identifier.parent, relExportPath))); }; // global scope variables globalVariables.forEach((variable) => { const parent = variable.identifiers?.[0]?.parent; if (parent?.type === utils_1.AST_NODE_TYPES.ImportNamespaceSpecifier) { lintVariable(variable, globalVariables, (0, esLintUtils_1.extractPathFromImport)(parent.parent)); } const extractPathFromVariableDeclarator = ({ init: node }) => { if (node?.type === utils_1.AST_NODE_TYPES.AwaitExpression) node = node.argument; if (node?.type === utils_1.AST_NODE_TYPES.ImportExpression) return (0, esLintUtils_1.extractPathFromImport)(node); }; if (parent?.type === utils_1.AST_NODE_TYPES.VariableDeclarator) { const relExportPath = extractPathFromVariableDeclarator(parent); if (relExportPath) { lintVariable(variable, globalVariables, relExportPath); } } if (parent?.type === utils_1.AST_NODE_TYPES.Property && parent.parent.type === utils_1.AST_NODE_TYPES.ObjectPattern && parent.parent.parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator) { const relExportPath = extractPathFromVariableDeclarator(parent.parent.parent); if (relExportPath) { lintNode(parent.key, relExportPath); } } }); // thenned dynamic imports scopeTree.scopes.forEach((scope) => { const blockParent = scope.block.parent; if (blockParent?.type !== utils_1.AST_NODE_TYPES.CallExpression) return; if (blockParent.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression) return; if (blockParent.callee.object.type !== utils_1.AST_NODE_TYPES.ImportExpression) return; const relExportPath = (0, esLintUtils_1.extractPathFromImport)(blockParent.callee.object); const moduleVariable = scope.variables?.[0]; if (!moduleVariable) return; if (moduleVariable.identifiers?.[0]?.parent.type === utils_1.AST_NODE_TYPES.Property && moduleVariable.identifiers?.[0]?.parent.parent.type === utils_1.AST_NODE_TYPES.ObjectPattern) { const objectPattern = moduleVariable.identifiers?.[0]?.parent.parent; lintNode(objectPattern, relExportPath); } else { lintVariable(moduleVariable, scope.variables, relExportPath); } }); }; exports.validateProgram = validateProgram; //# sourceMappingURL=validateProgram.js.map