{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport figlet from 'figlet'\nimport * as jsonc from 'jsonc-parser'\n\nconst init = (header?: string) => {\n  console.log('-----------------------------------------------')\n  console.log(header)\n  console.log('-----------------------------------------------')\n  console.log('*********** @korautils/alias-fixer ************')\n  console.log('-----------------------------------------------')\n  // console.log('-----------------------------------------------')\n  console.log('🔍 Finding tsconfig file...')\n  // console.log('-----------------------------------------------')\n  const tsconfig = getTsConfig()\n  // valido si tiene paths configurados, si no pues no hay nada que hacer...\n  if (!checkPaths(tsconfig)) {\n    console.log(\n      'ERROR: No se encontró el archivo tsconfig.json o no se encontró una configuración válida'\n    )\n    console.log('Se finaliza la operación.')\n    return\n  }\n\n  const dir = path.resolve(process.cwd(), getArgument('--dir', './'))\n  const types = getArgument('--types', 'ts,tsx,jsx,js').split(',')\n  const exclude = getProp(tsconfig, 'exclude', ['node_modules'])\n  console.log('🗂️  dir:', dir)\n  console.log('⚪️ types:', types)\n  console.log('🚫 exclude:', exclude)\n  const files = listFilesByTypes(dir, types, exclude)\n  // console.log(files)\n  replaceImportsWithAliases(files, tsconfig)\n  console.log('-----------------------------------------------')\n  console.log('✅ Process completed successfully.')\n  console.log('-----------------------------------------------')\n}\n\n/**\n * Replaces relative imports in files with aliases from tsconfig.\n * @param {string[]} files - List of file paths to process.\n * @param {any} tsconfig - The loaded tsconfig.json object.\n */\nfunction replaceImportsWithAliases(files: string[], tsconfig: any) {\n  const paths = tsconfig.compilerOptions?.paths || {}\n  const dir = path.resolve(\n    process.cwd(),\n    tsconfig.compilerOptions?.baseUrl || './'\n  )\n\n  const computedPaths: { alias: string; folders: string[] }[] = []\n  for (const alias in paths) {\n    if (Object.prototype.hasOwnProperty.call(paths, alias)) {\n      const folderPaths = paths[alias]\n      computedPaths.push({\n        alias: alias.replace(/\\/\\*{1,2}(\\*)?$/, ''),\n        folders: folderPaths.map((folder: string) =>\n          path.join(process.cwd(), folder.replace(/\\/\\*{1,2}(\\*)?$/, ''))\n        ),\n      })\n    }\n  }\n\n  files.forEach((file) => {\n    const content = fs.readFileSync(file, 'utf-8')\n\n    // Replace relative imports with alias\n    const updatedContent = content.replace(\n      /(import\\s+.*?['\"])(\\.{1,2}\\/.*?)(['\"])/g,\n      (fullMatch, prefix, relativePath, suffix) => {\n        // Calculate the absolute path of the imported file\n        const importedFilePath = path.resolve(path.dirname(file), relativePath)\n\n        // Navigate back specified number of folders\n        const backFoldersTo = countRelativePaths(relativePath)\n        let currentDir = path.dirname(file)\n        for (let i = 0; i < backFoldersTo; i++) {\n          currentDir = path.dirname(currentDir)\n        }\n\n        // If not within the base directory, return original path\n        if (!currentDir.startsWith(dir)) {\n          return fullMatch\n        }\n\n        // Check if the imported file is outside ALL configured path folders\n        const isOutsideAllPaths = computedPaths.every(\n          (aliasPath) =>\n            !aliasPath.folders.some((folderPath) =>\n              importedFilePath.startsWith(folderPath)\n            )\n        )\n\n        // If outside all paths, return original path\n        if (isOutsideAllPaths) {\n          return fullMatch\n        }\n\n        // Try to match and replace with the most specific alias\n        let bestMatch: { alias: string; relativeImportPath: string } | null =\n          null\n\n        computedPaths.forEach((aliasPath) => {\n          aliasPath.folders.forEach((folderPath) => {\n            // Check if the imported file is within this alias's folder path\n            if (importedFilePath.startsWith(folderPath)) {\n              // Calculate the relative path within the alias folder\n              const relativeImportPath = path.relative(\n                folderPath,\n                importedFilePath\n              )\n              const newPathCandidate = path.join(\n                aliasPath.alias,\n                relativeImportPath\n              )\n\n              // Choose the most specific (longest) match\n              if (\n                !bestMatch ||\n                newPathCandidate.length > bestMatch.relativeImportPath.length\n              ) {\n                bestMatch = {\n                  alias: aliasPath.alias,\n                  relativeImportPath: newPathCandidate,\n                }\n              }\n            }\n          })\n        })\n\n        // Return the best matching path or original if no match found\n        return bestMatch\n          ? `${prefix}${getProp(bestMatch, 'relativeImportPath')}${suffix}`\n          : fullMatch\n      }\n    )\n\n    if (content !== updatedContent) {\n      console.log('Updated import in:', file)\n      fs.writeFileSync(file, updatedContent, 'utf-8')\n    }\n  })\n}\n\nfunction countRelativePaths(path: string) {\n  // Expresión regular para buscar apariciones de ../\n  const regex = /\\.\\.\\//g\n  // Usa match para encontrar todas las coincidencias\n  const matches = path.match(regex)\n  // Devuelve la cantidad de coincidencias o 0 si no hay ninguna\n  return matches ? matches.length : 0\n}\n\n/**\n * Recursively lists files in a directory that match the specified extensions,\n * excluding certain directories or files.\n * @param {string} dir - The directory to search.\n * @param {string[]} types - The file extensions to include.\n * @param {string[]} exclude - The directories or files to exclude.\n * @returns {string[]} - An array of file paths that match the extensions.\n */\nfunction listFilesByTypes(\n  dir: string,\n  types: string[],\n  exclude: string[] = []\n) {\n  const matchedFiles: any = []\n\n  function recursiveRead(currentDir: string) {\n    const entries = fs.readdirSync(currentDir, { withFileTypes: true })\n    const excludedFiles = exclude.map((item) => {\n      const file = path.join(currentDir, item.trim())\n      if (fs.existsSync(file)) {\n        return file\n      }\n      return item.trim()\n    })\n\n    for (const entry of entries) {\n      const fullPath = path.join(currentDir, entry.name)\n\n      // Skip excluded directories or files\n      if (excludedFiles.some((excluded) => fullPath.includes(excluded))) {\n        continue\n      }\n\n      if (entry.isDirectory()) {\n        recursiveRead(fullPath)\n      } else if (entry.isFile()) {\n        const ext = path.extname(entry.name).slice(1) // Remove the leading dot\n        if (types.includes(ext)) {\n          matchedFiles.push(fullPath)\n        }\n      }\n    }\n  }\n\n  recursiveRead(dir)\n  return matchedFiles\n}\n\nfunction getArgument(key: string, defaultValue: string = './') {\n  const args = process.argv.slice(2) // Ignorar node y script\n  const prefix = `${key}=`\n\n  // Buscar el argumento que comienza con el prefix\n  const arg = args.find((arg) => arg.startsWith(prefix))\n\n  if (arg) {\n    return arg.slice(prefix.length)\n  } else {\n    return defaultValue\n  }\n}\n\nconst checkPaths = (tsconfig: any) => {\n  const baseUrl = getProp(tsconfig, 'compilerOptions.baseUrl')\n  const paths = getProp(tsconfig, 'compilerOptions.paths')\n\n  if (!tsconfig || !baseUrl || !paths) {\n    return false\n  }\n\n  const aliasList = Object.keys(paths).filter((alias) => alias.startsWith('@/'))\n  if (aliasList.length == 0) {\n    return false\n  }\n\n  return true\n}\n\nconst getTsConfig = () => {\n  const tsconfigPath = path.resolve(process.cwd(), 'tsconfig.json')\n  if (!fs.existsSync(tsconfigPath)) {\n    return\n  }\n\n  const tsconfigContent = fs.readFileSync(tsconfigPath, 'utf-8')\n  const parsedTsconfig = jsonc.parse(tsconfigContent)\n  return parsedTsconfig\n}\n\nfiglet('kora-utils', (err, data) => {\n  if (err) {\n    console.log('Algo salió mal...', err)\n    return\n  }\n\n  init(data)\n})\n\n/**\n * Obtiene una propiedad anidada de un objeto dado un path.\n *\n * @param obj - El objeto del cual obtener la propiedad.\n * @param path - La ruta a la propiedad, separada por puntos (e.g., \"a.b.c\").\n * @param defaultValue - Valor predeterminado si la propiedad no existe.\n * @returns El valor de la propiedad o el valor predeterminado.\n */\nfunction getProp<T>(\n  obj: Record<string, any>,\n  path: string,\n  defaultValue?: T\n): T | undefined {\n  if (!obj || typeof path !== 'string') {\n    return defaultValue\n  }\n\n  const keys = path.split('.') // Divide el path en claves\n  let current = obj\n\n  for (const key of keys) {\n    if (current && typeof current === 'object' && key in current) {\n      current = current[key] // Avanza al siguiente nivel del objeto\n    } else {\n      return defaultValue // Retorna el valor predeterminado si no existe\n    }\n  }\n\n  return current as T // Retorna el valor final encontrado\n}\n"],"mappings":"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","names":["import_fs","import_path","import_figlet","jsonc","init","header","tsconfig","getTsConfig","checkPaths","dir","path","getArgument","types","exclude","getProp","files","listFilesByTypes","replaceImportsWithAliases","paths","computedPaths","alias","folderPaths","folder","file","content","fs","updatedContent","fullMatch","prefix","relativePath","suffix","importedFilePath","backFoldersTo","countRelativePaths","currentDir","i","aliasPath","folderPath","bestMatch","relativeImportPath","newPathCandidate","regex","matches","matchedFiles","recursiveRead","entries","excludedFiles","item","entry","fullPath","excluded","ext","key","defaultValue","args","arg","baseUrl","tsconfigPath","tsconfigContent","figlet","err","data","obj","keys","current"]}