[+] API Doc generator

pull/17/head
Azalea 2024-02-28 20:52:23 -05:00
parent 5f4a7cd7c9
commit 10169b03ce
2 changed files with 124 additions and 0 deletions

60
docs/api-v2.md 100644
View File

@ -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

View File

@ -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<Class<*>>()
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<API>() }.forEach { fn ->
val endpoint = fn.findAnnotation<API>()!!.value.joinToString(", ")
val doc = fn.findAnnotation<Doc>()
println("\n**${base.replace("/api/v2", "")}$endpoint** : ${doc?.desc ?: "No description"}\n")
// Parameters
fn.parameters.filter { it.hasAnnotation<RP>() }.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)
}