UNPKG

alias-it

Version:

Intelligent TypeScript path mapping with auto-discovery and validation

1 lines 29.4 kB
{"version":3,"sources":["../src/cli.ts","../src/PathMapper.ts","../src/utils/fileUtils.ts","../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport { generatePathMappings, validatePathMappings, updateTsConfigMappings, getPathMappingSuggestions } from \"./index\";\nimport { PathMapper } from \"./PathMapper\";\nimport * as fs from \"fs-extra\";\nimport * as path from \"path\";\n\nconst program = new Command();\n\nprogram.name(\"alias-it\").description(\"Intelligent TypeScript path mapping with auto-discovery and validation\").version(\"1.0.0\");\n\nprogram\n .command(\"discover\")\n .description(\"Discover potential path mappings in the project\")\n .option(\"--root-dir <path>\", \"Root directory to scan\", process.cwd())\n .option(\"--output <path>\", \"Output file for results (JSON format)\")\n .action(async (options) => {\n const mapper = new PathMapper({ rootDir: options.rootDir });\n const discovered = await mapper.discoverPaths();\n console.log(`\\nFound ${discovered.length} potential mappings:\\n`);\n for (const item of discovered) {\n console.log(` @${item.alias} -> ${item.relativePath} (${item.type}, depth: ${item.depth})`);\n }\n if (options.output) {\n await fs.writeJson(options.output, discovered, { spaces: 2 });\n console.log(`\\nResults saved to: ${options.output}`);\n }\n });\n\nprogram\n .command(\"generate\")\n .description(\"Generate path mappings and optionally update tsconfig.json\")\n .option(\"--root-dir <path>\", \"Root directory to scan\", process.cwd())\n .option(\"--tsconfig <path>\", \"Path to tsconfig.json\", \"tsconfig.json\")\n .option(\"--output <path>\", \"Output file for mappings (JSON format)\")\n .option(\"--merge\", \"Merge with existing mappings\", true)\n .option(\"--no-merge\", \"Replace existing mappings\")\n .action(async (options) => {\n const result = await generatePathMappings({ rootDir: options.rootDir });\n console.log(`\\nGenerated ${Object.keys(result).length} mappings:\\n`);\n for (const [alias, mapping] of Object.entries(result)) {\n console.log(` ${alias}: \"${mapping}\"`);\n }\n if (options.merge !== false) {\n await updateTsConfigMappings(result, options.tsconfig, true, { rootDir: options.rootDir });\n console.log(\"✅ tsconfig.json updated successfully!\");\n }\n if (options.output) {\n await fs.writeJson(options.output, result, { spaces: 2 });\n console.log(`\\nMappings saved to: ${options.output}`);\n }\n });\n\nprogram\n .command(\"validate\")\n .description(\"Validate existing path mappings in tsconfig.json\")\n .option(\"--root-dir <path>\", \"Root directory to scan\", process.cwd())\n .option(\"--tsconfig <path>\", \"Path to tsconfig.json\", \"tsconfig.json\")\n .action(async (options) => {\n const isValid = await validatePathMappings(options.tsconfig, { rootDir: options.rootDir });\n if (isValid) {\n console.log(\"✅ All path mappings are valid!\");\n } else {\n console.log(\"❌ Some path mappings have issues.\");\n process.exit(1);\n }\n });\n\nprogram\n .command(\"suggest\")\n .description(\"Get suggestions for path mappings\")\n .option(\"--root-dir <path>\", \"Root directory to scan\", process.cwd())\n .action(async (options) => {\n const suggestions = await getPathMappingSuggestions({ rootDir: options.rootDir });\n if (suggestions.length === 0) {\n console.log(\"No suggestions available.\");\n } else {\n console.log(\"\\nSuggestions:\\n\");\n suggestions.forEach((suggestion, index) => {\n console.log(` ${index + 1}. ${suggestion}`);\n });\n }\n });\n\nprogram\n .command(\"update\")\n .description(\"Update tsconfig.json with new mappings from a file\")\n .requiredOption(\"--output <path>\", \"Input file with mappings (JSON format)\")\n .option(\"--tsconfig <path>\", \"Path to tsconfig.json\", \"tsconfig.json\")\n .option(\"--merge\", \"Merge with existing mappings\", true)\n .option(\"--no-merge\", \"Replace existing mappings\")\n .option(\"--root-dir <path>\", \"Root directory to scan\", process.cwd())\n .action(async (options) => {\n const mappings = await fs.readJson(options.output);\n await updateTsConfigMappings(mappings, options.tsconfig, options.merge, { rootDir: options.rootDir });\n console.log(\"✅ tsconfig.json updated successfully!\");\n });\n\nprogram.parseAsync(process.argv);\n","import * as path from \"path\";\nimport { FileUtils } from \"./utils/fileUtils\";\nimport { PathMapping, PathMapperOptions, DiscoveredPath, PathMapperResult, ValidationResult, ValidationIssue } from \"./types\";\n\nexport class PathMapper {\n private rootDir: string;\n private options: Required<PathMapperOptions>;\n\n constructor(options: PathMapperOptions = {}) {\n this.rootDir = options.rootDir || process.cwd();\n this.options = {\n rootDir: this.rootDir,\n includePatterns: options.includePatterns || [\"**/*.ts\", \"**/*.tsx\"],\n excludePatterns: options.excludePatterns || [\"**/*.d.ts\", \"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/.git/**\"],\n maxDepth: options.maxDepth || 3,\n autoGenerate: options.autoGenerate ?? true,\n validateExisting: options.validateExisting ?? true,\n };\n }\n\n /**\n * Discover potential path mappings in the project\n */\n async discoverPaths(): Promise<DiscoveredPath[]> {\n const discovered: DiscoveredPath[] = [];\n\n try {\n // Get TypeScript files\n const tsFiles = await FileUtils.getTypeScriptFiles(this.rootDir, this.options.includePatterns, this.options.excludePatterns);\n\n // Get directory structure\n const directories = await FileUtils.getDirectoryStructure(this.rootDir, this.options.maxDepth);\n\n // Process files\n for (const file of tsFiles) {\n const relativePath = path.relative(this.rootDir, file);\n const alias = FileUtils.generateAlias(file, this.rootDir);\n\n discovered.push({\n alias,\n path: file,\n relativePath,\n type: \"file\",\n depth: this.calculateDepth(relativePath),\n });\n }\n\n // Process directories\n for (const dir of directories) {\n const relativePath = path.relative(this.rootDir, dir);\n const alias = FileUtils.generateAlias(dir, this.rootDir);\n\n discovered.push({\n alias,\n path: dir,\n relativePath,\n type: \"directory\",\n depth: this.calculateDepth(relativePath),\n });\n }\n\n // Sort by depth and then by alias\n return discovered.sort((a, b) => {\n if (a.depth !== b.depth) {\n return a.depth - b.depth;\n }\n return a.alias.localeCompare(b.alias);\n });\n } catch (error) {\n throw new Error(`Failed to discover paths: ${error}`);\n }\n }\n\n /**\n * Generate path mappings from discovered paths\n */\n async generateMappings(): Promise<PathMapperResult> {\n const discovered = await this.discoverPaths();\n const mappings: PathMapping = {};\n const suggestions: string[] = [];\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // Group by alias to handle conflicts\n const aliasGroups = new Map<string, DiscoveredPath[]>();\n\n for (const item of discovered) {\n if (!aliasGroups.has(item.alias)) {\n aliasGroups.set(item.alias, []);\n }\n aliasGroups.get(item.alias)!.push(item);\n }\n\n // Process each alias group\n for (const [alias, items] of aliasGroups) {\n if (items.length === 1) {\n // No conflict, use the item\n const item = items[0];\n mappings[`@${alias}`] = item.relativePath;\n\n if (item.depth > 2) {\n suggestions.push(`Consider using a shorter alias for deep path: ${item.relativePath}`);\n }\n } else {\n // Conflict detected, resolve it\n const resolved = this.resolveAliasConflict(alias, items);\n mappings[`@${resolved.alias}`] = resolved.path;\n warnings.push(`Alias conflict resolved: ${alias} -> ${resolved.alias} for ${resolved.path}`);\n }\n }\n\n return {\n mappings,\n discovered,\n suggestions,\n warnings,\n errors,\n };\n }\n\n /**\n * Validate existing path mappings in tsconfig.json\n */\n async validateExistingMappings(tsConfigPath?: string): Promise<ValidationResult> {\n const configPath = tsConfigPath || path.join(this.rootDir, \"tsconfig.json\");\n const issues: ValidationIssue[] = [];\n\n try {\n if (!(await FileUtils.pathExists(configPath))) {\n issues.push({\n type: \"error\",\n message: \"tsconfig.json not found\",\n path: configPath,\n });\n return { isValid: false, issues };\n }\n\n const config = await FileUtils.readTsConfig(configPath);\n const pathMappings = config.compilerOptions?.paths || {};\n\n for (const [alias, mapping] of Object.entries(pathMappings)) {\n const mappingPath = Array.isArray(mapping) ? mapping[0] : mapping;\n\n if (!FileUtils.validatePathMapping(mappingPath, this.rootDir)) {\n issues.push({\n type: \"error\",\n message: `Invalid path mapping: ${alias} -> ${mappingPath}`,\n path: mappingPath,\n suggestion: \"Remove or fix this mapping\",\n });\n } else {\n // Check for potential improvements\n const discovered = await this.discoverPaths();\n const betterMapping = this.findBetterMapping(alias, mappingPath, discovered);\n\n if (betterMapping) {\n issues.push({\n type: \"info\",\n message: `Consider using shorter path: ${betterMapping}`,\n path: mappingPath,\n suggestion: betterMapping,\n });\n }\n }\n }\n\n return {\n isValid: issues.filter((issue) => issue.type === \"error\").length === 0,\n issues,\n };\n } catch (error) {\n issues.push({\n type: \"error\",\n message: `Failed to validate mappings: ${error}`,\n path: configPath,\n });\n return { isValid: false, issues };\n }\n }\n\n /**\n * Update tsconfig.json with new path mappings\n */\n async updateTsConfig(newMappings: PathMapping, tsConfigPath?: string, merge: boolean = true): Promise<void> {\n const configPath = tsConfigPath || path.join(this.rootDir, \"tsconfig.json\");\n\n try {\n let config: any;\n\n if (await FileUtils.pathExists(configPath)) {\n config = await FileUtils.readTsConfig(configPath);\n } else {\n config = {\n compilerOptions: {\n target: \"ES2020\",\n module: \"commonjs\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n },\n };\n }\n\n // Ensure compilerOptions exists\n if (!config.compilerOptions) {\n config.compilerOptions = {};\n }\n\n // Update path mappings\n if (merge && config.compilerOptions.paths) {\n config.compilerOptions.paths = { ...config.compilerOptions.paths, ...newMappings };\n } else {\n config.compilerOptions.paths = newMappings;\n }\n\n await FileUtils.writeTsConfig(configPath, config);\n } catch (error) {\n throw new Error(`Failed to update tsconfig.json: ${error}`);\n }\n }\n\n /**\n * Get intelligent suggestions for path mappings\n */\n async getSuggestions(): Promise<string[]> {\n const discovered = await this.discoverPaths();\n const suggestions: string[] = [];\n\n // Analyze import patterns\n const importPatterns = await this.analyzeImportPatterns();\n\n for (const pattern of importPatterns) {\n if (pattern.count > 5) {\n // Suggest for frequently used patterns\n suggestions.push(`Consider creating alias for: ${pattern.pattern} (used ${pattern.count} times)`);\n }\n }\n\n // Suggest common directory aliases\n const commonDirs = [\"components\", \"utils\", \"types\", \"services\", \"hooks\", \"pages\"];\n for (const dir of commonDirs) {\n const dirPath = path.join(this.rootDir, \"src\", dir);\n if (await FileUtils.pathExists(dirPath)) {\n suggestions.push(`Consider adding alias for common directory: @${dir} -> src/${dir}`);\n }\n }\n\n return suggestions;\n }\n\n private calculateDepth(relativePath: string): number {\n return relativePath.split(path.sep).length - 1;\n }\n\n private resolveAliasConflict(alias: string, items: DiscoveredPath[]): { alias: string; path: string } {\n // Prefer files over directories\n const files = items.filter((item) => item.type === \"file\");\n const directories = items.filter((item) => item.type === \"directory\");\n\n if (files.length > 0) {\n // Use the file with the shortest path\n const shortestFile = files.reduce((shortest, current) => (current.relativePath.length < shortest.relativePath.length ? current : shortest));\n return { alias: shortestFile.alias, path: shortestFile.relativePath };\n }\n\n if (directories.length > 0) {\n // Use the directory with the shortest path\n const shortestDir = directories.reduce((shortest, current) => (current.relativePath.length < shortest.relativePath.length ? current : shortest));\n return { alias: shortestDir.alias, path: shortestDir.relativePath };\n }\n\n // Fallback to first item\n return { alias: items[0].alias, path: items[0].relativePath };\n }\n\n private findBetterMapping(alias: string, currentPath: string, discovered: DiscoveredPath[]): string | null {\n // Find if there's a shorter path that leads to the same destination\n const targetPath = path.resolve(this.rootDir, currentPath);\n\n for (const item of discovered) {\n const itemFullPath = path.resolve(this.rootDir, item.relativePath);\n if (itemFullPath === targetPath && item.relativePath.length < currentPath.length) {\n return item.relativePath;\n }\n }\n\n return null;\n }\n\n private async analyzeImportPatterns(): Promise<Array<{ pattern: string; count: number }>> {\n // This is a simplified implementation\n // In a real implementation, you would parse TypeScript files and analyze import statements\n return [];\n }\n}\n","import * as fs from 'fs-extra';\nimport * as path from 'path';\nimport { glob } from 'glob';\n\nexport class FileUtils {\n /**\n * Check if a path exists and is accessible\n */\n static async pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get all TypeScript files in a directory recursively\n */\n static async getTypeScriptFiles(\n rootDir: string,\n includePatterns: string[] = ['**/*.ts', '**/*.tsx'],\n excludePatterns: string[] = ['**/*.d.ts', '**/node_modules/**', '**/dist/**', '**/build/**']\n ): Promise<string[]> {\n const patterns = includePatterns.map(pattern => path.join(rootDir, pattern));\n const excludePatternsWithRoot = excludePatterns.map(pattern => path.join(rootDir, pattern));\n \n const files: string[] = [];\n \n for (const pattern of patterns) {\n const matches = await glob(pattern, {\n ignore: excludePatternsWithRoot,\n absolute: true,\n nodir: true\n });\n files.push(...matches);\n }\n \n return [...new Set(files)];\n }\n\n /**\n * Get directory structure up to a certain depth\n */\n static async getDirectoryStructure(\n rootDir: string,\n maxDepth: number = 3,\n currentDepth: number = 0\n ): Promise<string[]> {\n if (currentDepth >= maxDepth) {\n return [];\n }\n\n try {\n const items = await fs.readdir(rootDir);\n const directories: string[] = [];\n\n for (const item of items) {\n const fullPath = path.join(rootDir, item);\n const stat = await fs.stat(fullPath);\n \n if (stat.isDirectory()) {\n directories.push(fullPath);\n const subDirs = await this.getDirectoryStructure(fullPath, maxDepth, currentDepth + 1);\n directories.push(...subDirs);\n }\n }\n\n return directories;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Generate a meaningful alias from a path\n */\n static generateAlias(filePath: string, rootDir: string): string {\n const relativePath = path.relative(rootDir, filePath);\n const withoutExt = path.parse(relativePath);\n \n // Remove common prefixes and generate camelCase alias\n let alias = withoutExt.name\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .replace(/\\s+(\\w)/g, (_: string, char: string) => char.toUpperCase())\n .replace(/^(\\w)/, (_: string, char: string) => char.toLowerCase());\n \n // If it's a directory, use the directory name\n if (withoutExt.ext === '') {\n alias = path.basename(filePath);\n }\n \n // Ensure alias starts with a letter\n if (!/^[a-zA-Z]/.test(alias)) {\n alias = 'p' + alias;\n }\n \n return alias;\n }\n\n /**\n * Validate if a path mapping is valid\n */\n static validatePathMapping(mapping: string, rootDir: string): boolean {\n const fullPath = path.resolve(rootDir, mapping);\n return fs.existsSync(fullPath);\n }\n\n /**\n * Read tsconfig.json file\n */\n static async readTsConfig(configPath: string): Promise<any> {\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n throw new Error(`Failed to read tsconfig.json: ${error}`);\n }\n }\n\n /**\n * Write tsconfig.json file\n */\n static async writeTsConfig(configPath: string, config: any): Promise<void> {\n try {\n await fs.writeFile(configPath, JSON.stringify(config, null, 2));\n } catch (error) {\n throw new Error(`Failed to write tsconfig.json: ${error}`);\n }\n }\n} ","export { PathMapper } from './PathMapper';\nexport * from './types';\n\nimport { PathMapper } from './PathMapper';\nimport { PathMapping, PathMapperOptions } from './types';\n\nexport async function generatePathMappings(options?: PathMapperOptions): Promise<PathMapping> {\n const mapper = new PathMapper(options);\n const result = await mapper.generateMappings();\n return result.mappings;\n}\n\nexport async function validatePathMappings(\n tsConfigPath?: string,\n options?: PathMapperOptions\n): Promise<boolean> {\n const mapper = new PathMapper(options);\n const result = await mapper.validateExistingMappings(tsConfigPath);\n return result.isValid;\n}\n\nexport async function updateTsConfigMappings(\n mappings: PathMapping,\n tsConfigPath?: string,\n merge?: boolean,\n options?: PathMapperOptions\n): Promise<void> {\n const mapper = new PathMapper(options);\n await mapper.updateTsConfig(mappings, tsConfigPath, merge);\n}\n\nexport async function getPathMappingSuggestions(options?: PathMapperOptions): Promise<string[]> {\n const mapper = new PathMapper(options);\n return await mapper.getSuggestions();\n} "],"mappings":"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","names":["path","stat","fs"]}