diff --git a/chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/EcmaImportHelper.kt b/chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/EcmaImportHelper.kt new file mode 100644 index 00000000..6985e8a6 --- /dev/null +++ b/chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/EcmaImportHelper.kt @@ -0,0 +1,102 @@ +package chapi.ast.typescriptast + +import java.io.File + +enum class OS { + WINDOWS, LINUX, MAC, SOLARIS +} + +fun getOS(): OS? { + val os = System.getProperty("os.name").lowercase() + return when { + os.contains("win") -> { + OS.WINDOWS + } + + os.contains("nix") || os.contains("nux") || os.contains("aix") -> { + OS.LINUX + } + + os.contains("mac") -> { + OS.MAC + } + + os.contains("sunos") -> { + OS.SOLARIS + } + + else -> null + } +} + +object EcmaImportHelper { + /** + * Converts a TypeScript import statement to the corresponding import statement in the target language. + * + * This method takes an import statement in TypeScript and converts it to the equivalent import statement in the target language. It handles the conversion of file paths and package names. + * + * @param importSource The import statement to be converted. It should be in the format of a TypeScript import statement. + * @param filePath The file path of the current file. This is used to resolve relative file paths in the import statement. + * + * @return The converted import statement in the target language. + * + * Usage: + * ```kotlin + * val output = EcmaImportHelper.convertTypeScriptImport("../component", "src/main.tsx") + * println(output) // "@.src.component" + * ``` + */ + fun convertTypeScriptImport(importSource: String, filePath: String): String { + var imp = importSource + if (!imp.startsWith("@")) { + imp = importConvert(filePath, imp) + if (imp.startsWith("src/")) { + imp = imp.replaceFirst("src/", "@/") + } + } + + imp = imp.replace("/", ".") + return imp + } + + + /** + * Converts the import path to the corresponding file path based on the given file path and import path. + * + * @param filepath The file path of the current file. + * @param importPath The import path to be converted. + * @return The converted file path. + */ + fun importConvert(filepath: String, importPath: String): String { + // import "@/src/component/Hello.js" + val isResolvePath = importPath.startsWith("@/") + if (isResolvePath) { + var pathname = importPath.removeRange(0, 2) + pathname = "src/$pathname" + + if (getOS() == OS.WINDOWS) pathname = pathname.replace("\\", "/") + + return pathname + } + + if (importPath.startsWith("./") || importPath.startsWith("../")) { + var file = File(filepath) + + // use parent to convert + if (file.extension.isNotEmpty()) { + // src/main.tsx don't have parent + if (file.parentFile != null) { + file = file.parentFile + } + } + + val resolve = file.resolve(File(importPath)) + return resolve.normalize().toString() + } + + var finalPath = importPath + if (getOS() == OS.WINDOWS) finalPath = finalPath.replace("\\", "/") + return finalPath + } + +} diff --git a/chapi-ast-typescript/src/test/kotlin/chapi/ast/typescriptast/EcmaImportHelperTest.kt b/chapi-ast-typescript/src/test/kotlin/chapi/ast/typescriptast/EcmaImportHelperTest.kt new file mode 100644 index 00000000..7dcf4105 --- /dev/null +++ b/chapi-ast-typescript/src/test/kotlin/chapi/ast/typescriptast/EcmaImportHelperTest.kt @@ -0,0 +1,59 @@ +package chapi.ast.typescriptast; + +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class EcmaImportHelperTest { + + @Test + fun should_convertTypeScriptImport_when_importSourceStartsWithAt() { + // given + val importSource = "@/src/component" + val filePath = "src/main.tsx" + + // when + val result = EcmaImportHelper.convertTypeScriptImport(importSource, filePath) + + // then + assertEquals("@.src.component", result) + } + + @Test + fun should_convertTypeScriptImport_when_importSourceDoesNotStartWithAt() { + // given + val importSource = "../component" + val filePath = "src/main.tsx" + + // when + val result = EcmaImportHelper.convertTypeScriptImport(importSource, filePath) + + // then + assertEquals("component", result) + } + + @Test + fun should_convertTypeScriptImport_when_importSourceStartsWithSrc() { + // given + val importSource = "src/component" + val filePath = "src/main.tsx" + + // when + val result = EcmaImportHelper.convertTypeScriptImport(importSource, filePath) + + // then + assertEquals("@.component", result) + } + + @Test + fun should_convertTypeScriptImport_when_importSourceContainsSlash() { + // given + val importSource = "src/component/subcomponent" + val filePath = "src/main.tsx" + + // when + val result = EcmaImportHelper.convertTypeScriptImport(importSource, filePath) + + // then + assertEquals("@.component.subcomponent", result) + } +}