UNPKG

knip

Version:

Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects

75 lines (74 loc) 2.94 kB
import { getCachedExportedIdentifiers, setCachedExportedIdentifiers } from './cache.js'; import { forEachAliasReExport, forEachNamespaceReExport, forEachPassThroughReExport, getStarReExportSources, } from './visitors.js'; export const getExportedIdentifiers = (graph, filePath, visited = new Set()) => { if (visited.has(filePath)) return new Map(); visited.add(filePath); const cached = getCachedExportedIdentifiers(graph, filePath); if (cached) return cached; const node = graph.get(filePath); if (!node) return new Map(); const identifiers = new Map(); const addIdentifier = (identifier, isDuplicate = false) => { if (identifiers.has(identifier)) { identifiers.set(identifier, true); } else { identifiers.set(identifier, isDuplicate); } }; for (const identifier of node.exports.keys()) { if (identifier === 'default') continue; addIdentifier(identifier); } if (node.imports?.internal) { for (const [importedPath, importDetails] of node.imports.internal) { forEachPassThroughReExport(importDetails, (id, _sources) => { if (id !== 'default') addIdentifier(id); }); forEachAliasReExport(importDetails, (_id, alias, _sources) => { addIdentifier(alias); }); forEachNamespaceReExport(importDetails, (namespace, _sources) => { addIdentifier(namespace, true); }); const starSources = getStarReExportSources(importDetails); if (starSources) { const nestedIdentifiers = getExportedIdentifiers(graph, importedPath, new Set(visited)); for (const [nestedId, isNestedDuplicate] of nestedIdentifiers) { if (nestedId !== 'default') addIdentifier(nestedId, isNestedDuplicate); } } } } setCachedExportedIdentifiers(graph, filePath, identifiers); return identifiers; }; export const hasStrictlyEnumReferences = (importsForExport, identifier) => { if (!importsForExport || !importsForExport.refs.has(identifier)) return false; for (const ref of importsForExport.refs) { if (ref.startsWith(`${identifier}.`)) return false; } return true; }; export const getIssueType = (hasOnlyNsReference, isType) => { if (hasOnlyNsReference) return isType ? 'nsTypes' : 'nsExports'; return isType ? 'types' : 'exports'; }; export const findImportRef = (graph, importingFile, importedFile, identifier) => { const node = graph.get(importingFile); if (!node) return undefined; for (const _import of node.imports.imports) { if (_import.filePath === importedFile && _import.identifier === identifier) return _import; } };