UNPKG

ngx-unused

Version:

Detect unused classes (components, pipes, services and directives) defined in Angular workspace.

61 lines (60 loc) 2.63 kB
import { stdout } from 'process'; import { RELEVANT_DECORATOR_NAMES } from '../constants.js'; import { print } from '../output.js'; import { hasUsagesByPipeName } from './hasUsagesByPipeName.js'; import { hasUsagesBySelectors } from './hasUsagesBySelectors.js'; import { hasUsagesInTs } from './hasUsagesInTs.js'; import { TemplateService } from './templateService.js'; export function findUnusedClasses(sourceFiles) { const classes = sourceFiles .filter(file => !file.getBaseName().includes('.spec.ts')) .flatMap(file => file.getClasses()) .filter(declaration => getRelevantDecorator(declaration) !== undefined); const componentClasses = classes .filter(declaration => { var _a; return ((_a = getRelevantDecorator(declaration)) === null || _a === void 0 ? void 0 : _a.getFullName()) === 'Component'; }) .map(getRelevantDecorator) .filter(decorator => decorator !== undefined); const templateService = new TemplateService(componentClasses); if (stdout.isTTY) { print(`Found ${classes.length} classes from ${sourceFiles.length} files.\n`); } return classes .filter((declaration, index, { length }) => { const percentage = Math.round(((index + 1) / length) * 100); if (stdout.isTTY) { print(`Analyzing ${index + 1}/${length} (${percentage}%)`, true); if (index === length - 1) stdout.write('\n'); } return !isUsed(declaration, templateService); }) .map(asResult); } function isUsed(declaration, templateService) { const relevantDecorator = getRelevantDecorator(declaration); const classType = relevantDecorator.getFullName(); const hasTsUsages = hasUsagesInTs(declaration); if (hasTsUsages) { return true; } if (classType === 'Component' || classType === 'Directive') { return hasUsagesBySelectors(relevantDecorator, templateService); } if (classType === 'Pipe') { return hasUsagesByPipeName(relevantDecorator, templateService); } return false; } function asResult(declaration) { var _a; const sourceFile = declaration.getSourceFile(); return { classType: getRelevantDecorator(declaration).getFullName(), className: (_a = declaration.getName()) !== null && _a !== void 0 ? _a : '', fileName: sourceFile.getBaseName(), directory: sourceFile.getDirectory().getPath().toString(), }; } function getRelevantDecorator(classDeclaration) { return classDeclaration.getDecorator(decorator => RELEVANT_DECORATOR_NAMES.includes(decorator.getFullName())); }