mirror of https://github.com/dexidp/dex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.0 KiB
159 lines
3.0 KiB
package gendoc |
|
|
|
import ( |
|
"bytes" |
|
"fmt" |
|
"strconv" |
|
"strings" |
|
"text/template" |
|
"unicode" |
|
) |
|
|
|
var funcs = template.FuncMap{ |
|
"renderJSON": func(i interface{}) string { |
|
if s, ok := i.(Schema); ok { |
|
return s.toJSON() |
|
} |
|
return "" |
|
}, |
|
"toLink": toLink, |
|
"toCodeStr": func(code int) string { |
|
if code == CodeDefault { |
|
return "default" |
|
} |
|
return strconv.Itoa(code) |
|
}, |
|
} |
|
|
|
var markdownTmpl = template.Must(template.New("md").Funcs(funcs).Parse(` |
|
# {{ .Title }} |
|
|
|
{{ .Description }} |
|
|
|
__Version:__ {{ .Version }} |
|
|
|
## Models |
|
|
|
{{ range $i, $model := .Models }} |
|
### {{ $model.Name }} |
|
|
|
{{ $model.Description }} |
|
|
|
{{ $model | renderJSON }} |
|
{{ end }} |
|
|
|
## Paths |
|
|
|
{{ range $i, $path := .Paths }} |
|
### {{ $path.Method }} {{ $path.Path }} |
|
|
|
> __Summary__ |
|
|
|
> {{ $path.Summary }} |
|
|
|
> __Description__ |
|
|
|
> {{ $path.Description }} |
|
|
|
{{ if $path.Parameters }} |
|
> __Parameters__ |
|
|
|
> |Name|Located in|Description|Required|Type| |
|
|:-----|:-----|:-----|:-----|:-----| |
|
{{ range $i, $p := $path.Parameters }}| {{ $p.Name }} | {{ $p.LocatedIn }} | {{ $p.Description }} | {{ if $p.Required }}Yes{{ else }}No{{ end }} | {{ $p.Type | toLink }} | |
|
{{ end }} |
|
{{ end }} |
|
> __Responses__ |
|
|
|
> |Code|Description|Type| |
|
|:-----|:-----|:-----| |
|
{{ range $i, $r := $path.Responses }}| {{ $r.Code | toCodeStr }} | {{ $r.Description }} | {{ $r.Type | toLink }} | |
|
{{ end }} |
|
{{ end }} |
|
`)) |
|
|
|
func (doc Document) MarshalMarkdown() ([]byte, error) { |
|
var b bytes.Buffer |
|
if err := markdownTmpl.Execute(&b, doc); err != nil { |
|
return nil, err |
|
} |
|
return b.Bytes(), nil |
|
} |
|
|
|
func (m Schema) toJSON() string { |
|
var b bytes.Buffer |
|
b.WriteString("```\n") |
|
m.writeJSON(&b, "", true) |
|
b.WriteString("\n```") |
|
return b.String() |
|
} |
|
|
|
var indentStr = " " |
|
|
|
func (m Schema) writeJSON(b *bytes.Buffer, indent string, first bool) { |
|
if m.Ref != "" { |
|
b.WriteString(m.Ref) |
|
return |
|
} |
|
if first { |
|
b.WriteString(indent) |
|
} |
|
|
|
switch m.Type { |
|
case TypeArray: |
|
b.WriteString("[") |
|
for i, c := range m.Children { |
|
if i > 0 { |
|
b.WriteString(",") |
|
} |
|
b.WriteString("\n") |
|
b.WriteString(indent + indentStr) |
|
c.writeJSON(b, indent+indentStr, false) |
|
} |
|
b.WriteString("\n" + indent + "]") |
|
case TypeObject: |
|
b.WriteString("{") |
|
for i, c := range m.Children { |
|
if i > 0 { |
|
b.WriteString(",") |
|
} |
|
b.WriteString("\n") |
|
b.WriteString(indent + indentStr + c.Name + ": ") |
|
c.writeJSON(b, indent+indentStr, false) |
|
} |
|
b.WriteString("\n" + indent + "}") |
|
case TypeBool, TypeFloat, TypeInt, TypeString: |
|
b.WriteString(m.Type) |
|
if m.Description != "" { |
|
b.WriteString(" // ") |
|
b.WriteString(m.Description) |
|
} |
|
} |
|
} |
|
|
|
func toAnchor(s string) string { |
|
var b bytes.Buffer |
|
r := strings.NewReader(s) |
|
for { |
|
r, _, err := r.ReadRune() |
|
if err != nil { |
|
return b.String() |
|
} |
|
switch { |
|
case r == ' ': |
|
b.WriteRune('-') |
|
case 'a' <= r && r <= 'z': |
|
b.WriteRune(r) |
|
case 'A' <= r && r <= 'Z': |
|
b.WriteRune(unicode.ToLower(r)) |
|
} |
|
} |
|
} |
|
|
|
func toLink(s string) string { |
|
switch s { |
|
case "string", "boolean", "integer", "": |
|
return s |
|
} |
|
return fmt.Sprintf("[%s](#%s)", s, toAnchor(s)) |
|
}
|
|
|