diff --git a/pages/apiview/apidocs/apidocs.go b/pages/apiview/apidocs/apidocs.go new file mode 100644 index 00000000..5d3ccdfb --- /dev/null +++ b/pages/apiview/apidocs/apidocs.go @@ -0,0 +1,54 @@ +package apidocs + +import ( + "reflect" + "unicode" + + "github.com/aerogo/aero" + "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/utils" +) + +// ByType renders the api docs page for the given type. +func ByType(typeName string) func(*aero.Context) string { + return func(ctx *aero.Context) string { + t := arn.API.Type(typeName) + fields := []*utils.APIField{} + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + + if field.Anonymous || !unicode.IsUpper(rune(field.Name[0])) { + continue + } + + typeName := "" + + switch field.Type.Kind() { + case reflect.Ptr: + typeName = field.Type.Elem().Name() + + case reflect.Slice: + sliceElementType := field.Type.Elem() + + if sliceElementType.Kind() == reflect.Ptr { + sliceElementType = sliceElementType.Elem() + } + + typeName = sliceElementType.Name() + "[]" + + default: + typeName = field.Type.Name() + } + + fields = append(fields, &utils.APIField{ + Name: field.Name, + JSON: field.Tag.Get("json"), + Type: typeName, + }) + } + + return ctx.HTML(components.APIDocs(t, fields)) + } +} diff --git a/pages/apiview/apidocs/apidocs.pixy b/pages/apiview/apidocs/apidocs.pixy new file mode 100644 index 00000000..9829d846 --- /dev/null +++ b/pages/apiview/apidocs/apidocs.pixy @@ -0,0 +1,21 @@ +component APIDocs(t reflect.Type, fields []*utils.APIField) + h1= "API: " + t.Name() + + table + thead + tr + th Field name + th JavaScript notation + th Type + tbody + each field in fields + tr + td= field.Name + td= field.JSON + td= field.Type + + + .corner-buttons + a.button(href="/api") + Icon("code") + span Overview \ No newline at end of file diff --git a/pages/index.go b/pages/index.go index 997269dc..f3a3a28c 100644 --- a/pages/index.go +++ b/pages/index.go @@ -1,6 +1,8 @@ package pages import ( + "strings" + "github.com/aerogo/aero" "github.com/aerogo/layout" "github.com/animenotifier/arn" @@ -12,6 +14,7 @@ import ( "github.com/animenotifier/notify.moe/pages/animelist" "github.com/animenotifier/notify.moe/pages/animelistitem" "github.com/animenotifier/notify.moe/pages/apiview" + "github.com/animenotifier/notify.moe/pages/apiview/apidocs" "github.com/animenotifier/notify.moe/pages/calendar" "github.com/animenotifier/notify.moe/pages/character" "github.com/animenotifier/notify.moe/pages/charge" @@ -85,6 +88,11 @@ func Configure(app *aero.Application) { l.Page("/halloffame", halloffame.Get) l.Page("/login", login.Get) l.Page("/api", apiview.Get) + + for name := range arn.DB.Types() { + l.Page("/api/"+strings.ToLower(name), apidocs.ByType(name)) + } + // l.Ajax("/dashboard", dashboard.Get) // l.Ajax("/best/anime", best.Get) // l.Ajax("/artworks", artworks.Get) diff --git a/utils/APIField.go b/utils/APIField.go new file mode 100644 index 00000000..8c9e5f69 --- /dev/null +++ b/utils/APIField.go @@ -0,0 +1,8 @@ +package utils + +// APIField describes a field in the API. +type APIField struct { + Name string + JSON string + Type string +}