UNPKG

sicua

Version:

A tool for analyzing project structure and dependencies

163 lines (162 loc) 6.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TranslationKeyFinder = void 0; const astUtils_1 = require("../utils/astUtils"); const contextExtractor_1 = require("../extractors/contextExtractor"); /** * Finds translation keys used in source code with enhanced context */ class TranslationKeyFinder { constructor() { this.translationKeys = []; this.analyzedFiles = new Set(); this.contextExtractor = new contextExtractor_1.ContextExtractor(); } /** * Finds all translation keys in source files * @param sourceFiles Map of source files to analyze * @returns Promise resolving when analysis is complete */ async findAllTranslationKeys(sourceFiles) { // Analyze each source file for (const [filePath, sourceFile] of sourceFiles.entries()) { // Skip files that we've already analyzed if (this.analyzedFiles.has(filePath)) { continue; } // Skip non-TypeScript/JavaScript files if (!(0, astUtils_1.isTypeScriptFile)(filePath)) { continue; } const results = this.analyzeSourceFile(sourceFile, filePath); // Add the keys to our collection this.translationKeys.push(...results.translationKeys); // Mark as analyzed this.analyzedFiles.add(filePath); } } /** * Gets the collected translation keys * @returns Array of translation keys */ getTranslationKeys() { return this.translationKeys; } /** * Analyzes a source file for translation hooks and calls * @param sourceFile Source file to analyze * @param filePath Path to the source file * @returns Analysis results with hooks and keys */ analyzeSourceFile(sourceFile, filePath) { // Find all translation hooks in the file (e.g., useTranslations) const hooks = (0, astUtils_1.findTranslationHooksInFile)(sourceFile, filePath); // Process each hook to find translation keys const foundKeys = []; for (const hook of hooks) { const translationCalls = this.processTranslationHook(hook, sourceFile, filePath); // Add the keys to our result foundKeys.push(...translationCalls); } return { hooks, translationKeys: foundKeys, }; } /** * Processes a translation hook to find translation keys * @param hook Translation hook to process * @param sourceFile Source file * @param filePath File path * @returns Array of translation keys */ processTranslationHook(hook, sourceFile, filePath) { const { varName, namespace, componentName } = hook; // Find all translation calls using this hook const translationCalls = (0, astUtils_1.findTranslationCalls)(sourceFile, varName); // Process each translation call return translationCalls.map((call) => this.processTranslationCall(call, namespace, componentName, sourceFile, filePath)); } /** * Processes a translation call to create a translation key with usage context * @param call Translation call * @param namespace Optional namespace * @param componentName Component name * @param sourceFile Source file * @param filePath File path * @returns Translation key with usage context */ processTranslationCall(call, namespace, componentName, sourceFile, filePath) { const { keyText, callNode } = { keyText: call.key, callNode: call.node }; // Create the basic translation key const basicKey = (0, astUtils_1.processTranslationKey)(keyText, namespace, componentName, callNode, sourceFile, filePath); // Enhance it with additional context return this.contextExtractor.enhanceKeyWithContext(basicKey, sourceFile); } /** * Groups translation keys by file path * @returns Map of file paths to arrays of translation keys */ groupKeysByFile() { const keysByFile = new Map(); for (const key of this.translationKeys) { const existing = keysByFile.get(key.filePath) || []; existing.push(key); keysByFile.set(key.filePath, existing); } return keysByFile; } /** * Finds files with the most translation keys * @param limit Maximum number of files to return * @returns Array of files sorted by key count */ findFilesWithMostKeys(limit = 10) { const keysByFile = this.groupKeysByFile(); return Array.from(keysByFile.entries()) .map(([filePath, keys]) => ({ filePath, keyCount: keys.length, keys, })) .sort((a, b) => b.keyCount - a.keyCount) .slice(0, limit); } /** * Finds translation keys in JSX context * @returns Array of keys used in JSX */ findKeysInJSX() { return this.translationKeys.filter((key) => key.usageContext.isInJSX); } /** * Finds translation keys in conditional rendering * @returns Array of keys used in conditional rendering */ findKeysInConditionals() { return this.translationKeys.filter((key) => key.usageContext.isInConditional); } /** * Finds translation keys in event handlers * @returns Array of keys used in event handlers */ findKeysInEventHandlers() { return this.translationKeys.filter((key) => key.usageContext.isInEventHandler); } /** * Groups translation keys by component * @returns Map of component names to arrays of translation keys */ groupKeysByComponent() { const keysByComponent = new Map(); for (const key of this.translationKeys) { // Use the parent component from context if available const componentName = key.usageContext.parentComponent || key.componentName; const existing = keysByComponent.get(componentName) || []; existing.push(key); keysByComponent.set(componentName, existing); } return keysByComponent; } } exports.TranslationKeyFinder = TranslationKeyFinder;