UNPKG

crapifyme

Version:

Ultra-fast developer productivity CLI tools - remove comments, logs, and more

278 lines 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImportTransformer = void 0; const types_1 = require("./types"); class ImportTransformer { constructor(options = {}) { this.indentation = ' '; this.options = { style: options.style || 'mixed', sort: options.sort !== false, group: options.group !== false, removeUnused: options.removeUnused !== false, mergeDuplicates: options.mergeDuplicates !== false, multilineThreshold: options.multilineThreshold || 3, aliases: options.aliases || [], preserveComments: options.preserveComments !== false }; } transformImports(imports, filePath, originalContent) { if (originalContent) { this.detectIndentation(originalContent); } let processedImports = [...imports]; if (this.options.mergeDuplicates) { processedImports = this.mergeDuplicateImports(processedImports); } if (this.options.removeUnused) { processedImports = this.removeUnusedImports(processedImports); } if (this.options.style !== 'mixed') { processedImports = this.convertImportPaths(processedImports, filePath); } if (this.options.group) { const groups = this.groupImports(processedImports); return this.renderImportGroups(groups); } if (this.options.sort) { processedImports = this.sortImports(processedImports); } return this.renderImports(processedImports); } detectIndentation(content) { const multilineMatch = content.match(/import\s*{[^}]*\n(\s+)[^}]/); if (multilineMatch && multilineMatch[1]) { this.indentation = multilineMatch[1]; return; } const lines = content.split('\n'); for (const line of lines) { const match = line.match(/^(\s+)\S/); if (match && match[1]) { this.indentation = match[1]; return; } } } mergeDuplicateImports(imports) { const sourceMap = new Map(); for (const importStmt of imports) { const key = `${importStmt.source}:${importStmt.importKind}`; if (!sourceMap.has(key)) { sourceMap.set(key, []); } sourceMap.get(key).push(importStmt); } const mergedImports = []; for (const [, group] of sourceMap) { if (group.length === 1) { mergedImports.push(group[0]); } else { mergedImports.push(this.mergeImportGroup(group)); } } return mergedImports; } mergeImportGroup(imports) { const mergedSpecifiers = []; const seenLocals = new Set(); for (const importStmt of imports) { for (const spec of importStmt.specifiers) { const key = `${spec.type}:${spec.local}:${spec.imported || ''}`; if (!seenLocals.has(key)) { mergedSpecifiers.push(spec); seenLocals.add(key); } } } return { source: imports[0].source, specifiers: mergedSpecifiers, importKind: imports[0].importKind, startPos: Math.min(...imports.map(i => i.startPos)), endPos: Math.max(...imports.map(i => i.endPos)), leadingComments: imports[0].leadingComments, trailingComments: imports[imports.length - 1].trailingComments }; } removeUnusedImports(imports) { return imports.filter(importStmt => { return importStmt.specifiers.length > 0; }); } convertImportPaths(imports, filePath) { return imports.map(importStmt => { const convertedSource = this.convertPath(importStmt.source, filePath); return { ...importStmt, source: convertedSource }; }); } convertPath(importPath, filePath) { if (this.isExternalModule(importPath)) { return importPath; } for (const alias of this.options.aliases) { if (alias.regex.test(importPath)) { return importPath.replace(alias.regex, alias.replacement); } } if (this.options.style === types_1.ImportStyle.ABSOLUTE) { return this.toAbsolutePath(importPath, filePath); } else if (this.options.style === types_1.ImportStyle.RELATIVE) { return this.toRelativePath(importPath, filePath); } return importPath; } isExternalModule(path) { return (!path.startsWith('.') && !path.startsWith('/') && !path.startsWith('@/') && !path.startsWith('~/')); } toAbsolutePath(importPath, filePath) { if (importPath.startsWith('./')) { const dir = filePath.split('/').slice(0, -1).join('/'); return `@/${dir}/${importPath.slice(2)}`.replace(/\/+/g, '/'); } if (importPath.startsWith('../')) { const dir = filePath.split('/').slice(0, -1); const parts = importPath.split('/'); let upCount = 0; for (const part of parts) { if (part === '..') { upCount++; dir.pop(); } else if (part !== '.') { dir.push(part); } } return `@/${dir.join('/')}`.replace(/\/+/g, '/'); } return importPath; } toRelativePath(importPath, filePath) { if (importPath.startsWith('@/')) { const currentDir = filePath.split('/').slice(0, -1); const targetPath = importPath.slice(2).split('/'); let relativePath = ''; let commonIndex = 0; while (commonIndex < Math.min(currentDir.length, targetPath.length) && currentDir[commonIndex] === targetPath[commonIndex]) { commonIndex++; } const upLevels = currentDir.length - commonIndex; relativePath = '../'.repeat(upLevels); relativePath += targetPath.slice(commonIndex).join('/'); return relativePath || './'; } return importPath; } groupImports(imports) { const groups = new Map([ [types_1.ImportGroupType.EXTERNAL, []], [types_1.ImportGroupType.INTERNAL, []], [types_1.ImportGroupType.RELATIVE, []] ]); for (const importStmt of imports) { const groupType = this.getImportGroupType(importStmt.source); groups.get(groupType).push(importStmt); } const result = []; if (groups.get(types_1.ImportGroupType.EXTERNAL).length > 0) { result.push({ type: types_1.ImportGroupType.EXTERNAL, imports: this.sortImports(groups.get(types_1.ImportGroupType.EXTERNAL)), priority: 1 }); } if (groups.get(types_1.ImportGroupType.INTERNAL).length > 0) { result.push({ type: types_1.ImportGroupType.INTERNAL, imports: this.sortImports(groups.get(types_1.ImportGroupType.INTERNAL)), priority: 2 }); } if (groups.get(types_1.ImportGroupType.RELATIVE).length > 0) { result.push({ type: types_1.ImportGroupType.RELATIVE, imports: this.sortImports(groups.get(types_1.ImportGroupType.RELATIVE)), priority: 3 }); } return result; } getImportGroupType(source) { if (source.startsWith('.')) { return types_1.ImportGroupType.RELATIVE; } if (source.startsWith('@/') || source.startsWith('~/')) { return types_1.ImportGroupType.INTERNAL; } return types_1.ImportGroupType.EXTERNAL; } sortImports(imports) { return imports.slice().sort((a, b) => { return a.source.localeCompare(b.source); }); } renderImportGroups(groups) { return groups .sort((a, b) => a.priority - b.priority) .map(group => this.renderImports(group.imports)) .filter(group => group.trim().length > 0) .join('\n\n'); } renderImports(imports) { return imports.map(importStmt => this.renderImport(importStmt)).join('\n'); } renderImport(importStmt) { const comments = this.renderComments(importStmt); const importLine = this.renderImportLine(importStmt); return comments ? `${comments}\n${importLine}` : importLine; } renderComments(importStmt) { if (!this.options.preserveComments) return ''; const comments = []; if (importStmt.leadingComments) { comments.push(...importStmt.leadingComments.map(c => `// ${c}`)); } return comments.join('\n'); } renderImportLine(importStmt) { const typePrefix = importStmt.importKind === 'type' ? 'type ' : ''; if (importStmt.specifiers.length === 0) { return `import${typePrefix ? ` ${typePrefix}` : ''} '${importStmt.source}';`; } const defaultSpecs = importStmt.specifiers.filter(s => s.type === 'default'); const namespaceSpecs = importStmt.specifiers.filter(s => s.type === 'namespace'); const namedSpecs = importStmt.specifiers.filter(s => s.type === 'named'); const parts = []; if (defaultSpecs.length > 0) { parts.push(defaultSpecs[0].local); } if (namespaceSpecs.length > 0) { parts.push(`* as ${namespaceSpecs[0].local}`); } if (namedSpecs.length > 0) { const namedItems = namedSpecs.map(spec => { const typePrefix = spec.importKind === 'type' ? 'type ' : ''; const name = spec.imported === spec.local ? spec.local : `${spec.imported} as ${spec.local}`; return `${typePrefix}${name}`; }); const shouldUseMultiline = namedItems.length > this.options.multilineThreshold; if (shouldUseMultiline) { parts.push(`{\n${this.indentation}${namedItems.join(',\n' + this.indentation)}\n}`); } else { parts.push(`{ ${namedItems.join(', ')} }`); } } const importList = parts.join(', '); return `import ${typePrefix}${importList} from '${importStmt.source}';`; } } exports.ImportTransformer = ImportTransformer; //# sourceMappingURL=import-transformer.js.map