From 10169b03cefba7a915daa83aec15f348ac1c72d3 Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:52:23 -0500 Subject: [PATCH] [+] API Doc generator --- docs/api-v2.md | 60 +++++++++++++++++ .../java/icu/samnyan/aqua/spring/GenDocs.kt | 64 +++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 docs/api-v2.md create mode 100644 src/main/java/icu/samnyan/aqua/spring/GenDocs.kt diff --git a/docs/api-v2.md b/docs/api-v2.md new file mode 100644 index 00000000..d6d11ad0 --- /dev/null +++ b/docs/api-v2.md @@ -0,0 +1,60 @@ + + +### CardController : /api/v2/card + +Located at: [icu.samnyan.aqua.net.CardController](icu/samnyan/aqua/net/CardController.kt) + +**/card/link** : Bind a card to the user. This action will migrate selected data from the card to the user's ghost card. + +* token: String +* cardId: String +* migrate: String +* **Returns**: Success message + +**/card/summary** : Get a summary of the card, including the user's name, rating, and last login date. + +* cardId: String +* **Returns**: Summary of the card + +**/card/unlink** : Unbind a card from the user. No data will be migrated during this action. + +* token: String +* cardId: String +* **Returns**: Success message + + +### UserRegistrar : /api/v2/user + +Located at: [icu.samnyan.aqua.net.UserRegistrar](icu/samnyan/aqua/net/UserRegistrar.kt) + +**/user/confirm-email** : Confirm email address with a token sent through email to the user. + +* token: String +* **Returns**: Success message + +**/user/me** : Get the information of the current logged-in user. + +* token: String +* **Returns**: User information + +**/user/login** : Login with email/username and password. This will also check if the email is verified and send another confirmation + +* email: String +* password: String +* turnstile: String +* **Returns**: JWT token + +**/user/register** : Register a new user. This will also create a ghost card for the user and send a confirmation email. + +* username: String +* email: String +* password: String +* turnstile: String +* **Returns**: Success message + +**/user/setting** : Validate and set a user setting field. + +* token: String +* key: String +* value: String +* **Returns**: Success message diff --git a/src/main/java/icu/samnyan/aqua/spring/GenDocs.kt b/src/main/java/icu/samnyan/aqua/spring/GenDocs.kt new file mode 100644 index 00000000..126e4469 --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/spring/GenDocs.kt @@ -0,0 +1,64 @@ +package icu.samnyan.aqua.spring + +import ext.API +import ext.Doc +import ext.RP +import java.io.File +import kotlin.reflect.full.declaredFunctions +import kotlin.reflect.full.findAnnotation +import kotlin.reflect.full.hasAnnotation +import kotlin.reflect.javaType + +const val PACKAGE_NAME = "icu.samnyan.aqua.net" + +@OptIn(ExperimentalStdlibApi::class) +fun main() { + val path = PACKAGE_NAME.replace('.', '/') + val resources = Thread.currentThread().contextClassLoader.getResources(path) + val classes = mutableListOf>() + + while (resources.hasMoreElements()) { + val resource = resources.nextElement() + File(resource.file).listFiles { _, name -> name.endsWith(".class") }?.forEach { + val className = it.name.substring(0, it.name.length - 6) + val fullClassName = "$PACKAGE_NAME.$className" + val clazz = Class.forName(fullClassName) + classes.add(clazz) + } + } + val apiCls = API::class.java + + var buf = "" + + fun println(s: String) { + buf += s + "\n" + kotlin.io.println(s) + } + + // Loop through all classes + classes.filter { it.isAnnotationPresent(apiCls) }.forEach { cls -> + val base = cls.getAnnotation(API::class.java).value.joinToString(", ") + println("\n\n### ${cls.simpleName} : $base\n") + println("Located at: [${cls.name}](${cls.name.replace('.', '/')}.kt)") + + // Loop through all functions + cls.kotlin.declaredFunctions.filter { it.hasAnnotation() }.forEach { fn -> + val endpoint = fn.findAnnotation()!!.value.joinToString(", ") + val doc = fn.findAnnotation() + + println("\n**${base.replace("/api/v2", "")}$endpoint** : ${doc?.desc ?: "No description"}\n") + + // Parameters + fn.parameters.filter { it.hasAnnotation() }.forEach { param -> + val paramName = param.name + val paramType = param.type.javaType.typeName.split('.').last() + println("* $paramName: $paramType") + } + + doc?.ret?.let { println("* **Returns**: $it") } + } + } + + // Write to docs/api-v2.md + File("docs/api-v2.md").writeText(buf) +} \ No newline at end of file