diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index d87646d..921f0e4 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -15,13 +15,24 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 21 - uses: actions/setup-java@v4.5.0 - with: - java-version: '21' - distribution: 'adopt' - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew build + - uses: actions/checkout@v2 + - name: Set up JDK 21 + uses: actions/setup-java@v4.5.0 + with: + java-version: '21' + distribution: 'adopt' + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew build + + # upload file:///home/runner/work/ts-generator/ts-generator/build/reports/tests/test/index.html + # Warning: No files were found with the provided path: ts-generator/build/reports/tests/test/. No artifacts will be uploaded. + - name: Upload test report to GitHub Actions + if: always() + uses: actions/upload-artifact@v4 + with: + name: 'test-report' + path: 'build/reports/tests/test/' + + diff --git a/src/main/kotlin/me/ntrrgc/tsGenerator/TypeScriptGenerator.kt b/src/main/kotlin/me/ntrrgc/tsGenerator/TypeScriptGenerator.kt index f1cd491..09d9e87 100644 --- a/src/main/kotlin/me/ntrrgc/tsGenerator/TypeScriptGenerator.kt +++ b/src/main/kotlin/me/ntrrgc/tsGenerator/TypeScriptGenerator.kt @@ -140,11 +140,7 @@ class TypeScriptGenerator( } private fun generateDefinition(): String { - return if (klass.java.isEnum) { - generateEnum(klass) - } else { - generateInterface(klass) - } + return generateInterface(klass) } @@ -169,7 +165,11 @@ class TypeScriptGenerator( ) arrayFromKType(kType) else if (classifier.isSubclassOf(Map::class)) - mapFromKType(kType) + try { + mapFromKType(kType) + } catch (_: Exception) { + nonPrimitiveFromKType(kType) + } else nonPrimitiveFromKType(kType) ) @@ -244,28 +244,37 @@ class TypeScriptGenerator( getIterableElementType(kType) ?: kType.arguments.singleOrNull()?.type ?: KotlinAnyOrNull } } - return "${formatKType(itemType).formatWithParenthesis()}[]" + // a Path is iterable and it returns Path s for subdirectories + return if (kType == itemType) + "${nonPrimitiveFromKType(kType)}[]" // can it be others like maps? + else + "${formatKType(itemType).formatWithParenthesis()}[]" } + // https://github.com/ntrrgc/ts-generator/pull/39/files#diff-15868d315697c109f701fa6b29d6b1beaabb6c461122d4cbca76194bba08da6eR194 + // GPLv3 does not apply for this function private fun mapFromKType(kType: KType): String { - // Use native JS associative object + val rawKeyType = kType.arguments[0].type ?: KotlinAnyOrNull val keyType = formatKType(rawKeyType) val valueType = formatKType(kType.arguments[1].type ?: KotlinAnyOrNull) - return if ((rawKeyType.classifier as? KClass<*>)?.java?.isEnum == true) - "{ [key in ${keyType.formatWithoutParenthesis()}]: ${valueType.formatWithoutParenthesis()} }" - else - "{ [key: ${keyType.formatWithoutParenthesis()}]: ${valueType.formatWithoutParenthesis()} }" - } - private fun generateEnum(klass: KClass<*>): String { - return "type ${klass.simpleName} = ${ - klass.java.enumConstants.joinToString(" | ") { constant: Any -> - constant.toString().toJSString() - } - };" + val isKeyEnum = (rawKeyType.classifier as? KClass<*>)?.java?.isEnum == true + + return when { + isKeyEnum -> + "{ [key in ${keyType.formatWithoutParenthesis()}]: ${valueType.formatWithoutParenthesis()} }" + + keyType.formatWithoutParenthesis() == "string" || keyType.formatWithoutParenthesis() == "number" -> + "{ [key: ${keyType.formatWithoutParenthesis()}]: ${valueType.formatWithoutParenthesis()} }" + + else -> + "Map<${keyType.formatWithoutParenthesis()}, ${valueType.formatWithoutParenthesis()}>" + } + } + private fun generateInterface(klass: KClass<*>): String { val supertypes = klass.supertypes .filterNot { it.classifier in ignoredSuperclasses } @@ -325,6 +334,9 @@ class TypeScriptGenerator( } catch (exception: kotlin.reflect.jvm.internal.KotlinReflectionInternalError) { print(exception.toString()) "" + } catch (exception: java.lang.IllegalArgumentException) { + print(exception.toString()) + "" } private fun functionsOf(klass: KClass<*>): String = try { diff --git a/src/test/kotlin/me/ntrrgc/tsGenerator/tests/generatorTests.kt b/src/test/kotlin/me/ntrrgc/tsGenerator/tests/generatorTests.kt index c08f0f7..8a9272c 100644 --- a/src/test/kotlin/me/ntrrgc/tsGenerator/tests/generatorTests.kt +++ b/src/test/kotlin/me/ntrrgc/tsGenerator/tests/generatorTests.kt @@ -77,21 +77,27 @@ fun runModuleGenerationWithoutVerification( ignoreSuperclasses: Set> = setOf(), voidType: VoidType = VoidType.NULL ) { - val generator = TypeScriptGenerator( - listOf(klass), mappings, classTransformers, - ignoreSuperclasses, intTypeName = "number", voidType = voidType - ) + try { + val generator = TypeScriptGenerator( + listOf(klass), mappings, classTransformers, + ignoreSuperclasses, intTypeName = "number", voidType = voidType + ) + + val modules = generator.definitionsAsModules - val modules = generator.definitionsAsModules + for (module in modules) { + println("file: ${module.key}") + println() + println("content: ${module.value}") + println() + } - for (module in modules) { - println("file: ${module.key}") - println() - println("content: ${module.value}") - println() + true shouldBe true + } catch (exception: Exception) { + exception.printStackTrace() + throw exception } - true shouldBe true } @Suppress("unused") @@ -967,8 +973,14 @@ class ModuleOutput : StringSpec({ class Tests : StringSpec({ "generates NPM package without spitting error" { - TypeScriptGenerator(listOf(ClassWithMethodsThatReturnsOrTakesFunctionalType::class)) - .generateNPMPackage("test-generated-package-types") - .writePackageTo(Path("./runs")) + try { + TypeScriptGenerator(listOf(ClassWithMethodsThatReturnsOrTakesFunctionalType::class)) + .generateNPMPackage("test-generated-package-types") + .writePackageTo(Path("./runs")) + } catch (exception: Exception) { + exception.printStackTrace() + throw exception + } + } }) \ No newline at end of file