UNPKG

knip

Version:

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

91 lines (90 loc) 3.86 kB
import { IGNORED_RUNTIME_DEPENDENCIES } from '../constants.js'; import { debugLog } from './debug.js'; import { toDebugString } from './input.js'; import { fromBinary, isBinary, isConfigPattern, isDeferResolveEntry, isDependency } from './input.js'; import { getPackageNameFromSpecifier } from './modules.js'; import { dirname, isAbsolute, isInternal, join } from './path.js'; import { _resolveSync } from './resolve.js'; const getWorkspaceFor = (input, chief, workspace) => (input.dir && chief.findWorkspaceByFilePath(`${input.dir}/`)) || (input.containingFilePath && chief.findWorkspaceByFilePath(input.containingFilePath)) || workspace; export const getReferencedInputsHandler = (collector, deputy, chief, isGitIgnored) => (input, workspace) => { const { specifier, containingFilePath } = input; if (!containingFilePath || IGNORED_RUNTIME_DEPENDENCIES.has(specifier)) return; if (isBinary(input)) { const binaryName = fromBinary(input); const inputWorkspace = getWorkspaceFor(input, chief, workspace); const isHandled = deputy.maybeAddReferencedBinary(inputWorkspace, binaryName); if (isHandled || input.optional) return; collector.addIssue({ type: 'binaries', filePath: containingFilePath, workspace: workspace.name, symbol: binaryName, specifier, }); return; } const packageName = getPackageNameFromSpecifier(specifier); if (packageName) { const isWorkspace = chief.workspacesByPkgName.has(packageName); const inputWorkspace = getWorkspaceFor(input, chief, workspace); if (inputWorkspace) { const isHandled = deputy.maybeAddReferencedExternalDependency(inputWorkspace, packageName); if (isWorkspace || isDependency(input)) { if (!isHandled) { if (!input.optional && ((deputy.isProduction && input.production) || !deputy.isProduction)) { collector.addIssue({ type: 'unlisted', filePath: containingFilePath, workspace: inputWorkspace.name, symbol: packageName ?? specifier, specifier, }); } return; } const ref = _resolveSync(specifier, dirname(containingFilePath)); if (ref && isInternal(ref) && !isGitIgnored(ref)) return ref; } if (isHandled) return; } } if (!isConfigPattern(input) && deputy.isProduction && !input.production) { return; } const baseDir = input.dir ?? dirname(containingFilePath); const filePath = isAbsolute(specifier) ? specifier : join(baseDir, specifier); const resolvedFilePath = _resolveSync(filePath, baseDir); if (resolvedFilePath && isInternal(resolvedFilePath)) { return isGitIgnored(resolvedFilePath) ? undefined : resolvedFilePath; } if (input.optional) return; if (!isInternal(filePath)) { collector.addIssue({ type: 'unlisted', filePath: containingFilePath, workspace: workspace.name, symbol: packageName ?? specifier, specifier, }); } else if (!isGitIgnored(filePath)) { if (!isDeferResolveEntry(input) && !isConfigPattern(input)) { collector.addIssue({ type: 'unresolved', filePath: containingFilePath, workspace: workspace.name, symbol: specifier, }); } else { debugLog(workspace.name, `Unable to resolve ${toDebugString(input)}`); } } };