Docs: Generate client pages (#45)

This commit is contained in:
Janos Dobronszki
2021-01-28 13:14:16 +00:00
committed by GitHub
parent efaafa546a
commit 9fba76fd4e
6 changed files with 187 additions and 78 deletions

View File

@@ -76,13 +76,6 @@ func main() {
os.Exit(1) os.Exit(1)
} }
contentFile := filepath.Join(workDir, postContentPath, serviceName+".md")
err = ioutil.WriteFile(contentFile, append([]byte("---\ntitle: "+serviceName+"\n---\n"), dat...), 0777)
if err != nil {
fmt.Printf("Failed to write post content to %v:\n%v\n", contentFile, string(outp))
os.Exit(1)
}
apiJSON := filepath.Join(serviceDir, "api-"+serviceName+".json") apiJSON := filepath.Join(serviceDir, "api-"+serviceName+".json")
js, err := ioutil.ReadFile(apiJSON) js, err := ioutil.ReadFile(apiJSON)
if err != nil { if err != nil {
@@ -99,7 +92,7 @@ func main() {
fmt.Println("Failed to unmarshal", err) fmt.Println("Failed to unmarshal", err)
os.Exit(1) os.Exit(1)
} }
err = saveSpec(contentFile, spec) err = saveSpec(dat, contentDir, serviceName, spec)
if err != nil { if err != nil {
fmt.Println("Failed to save to spec file", err) fmt.Println("Failed to save to spec file", err)
os.Exit(1) os.Exit(1)
@@ -129,68 +122,139 @@ func main() {
} }
} }
func saveSpec(filepath string, spec *openapi3.Swagger) error { type specType struct {
fi, err := os.OpenFile(filepath, os.O_APPEND|os.O_WRONLY, os.ModeAppend) name string
if err != nil { tag string
return err includeReadme bool
} filePostFix string
//spec.Paths[0].Parameters[0].MarshalJSON() titlePostFix string
//spec.Paths[0].Options template string
//spec.Paths[0].Post.RequestBody. }
tmpl, err := template.New("test").Funcs(template.FuncMap{
"params": func(p openapi3.Parameters) string { var specTypes = []specType{
ls := "" {
for _, v := range p { name: "default markdown",
//if v.Value.In == "body" { tag: "Readme",
bs, _ := v.MarshalJSON() filePostFix: ".md",
ls += string(bs) + ", " template: defTempl,
//} includeReadme: true,
} },
return ls {
}, name: "microjs markdown",
// @todo should take SpecRef here not RequestBodyRef tag: "Micro.js",
"schemaJSON": func(ref string) string { filePostFix: "-microjs.md",
for k, v := range spec.Components.Schemas { titlePostFix: " Micro.js",
// ie. #/components/requestBodies/PostsSaveRequest contains template: microJSTempl,
// SaveRequest, can't see any other way to correlate includeReadme: false,
if strings.HasSuffix(ref, k) { },
bs, _ := json.MarshalIndent(schemaToMap(v, spec.Components.Schemas), "", " ") }
return string(bs)
var servicesToTags = map[string][]string{
"users": []string{"Backend"},
"helloworld": []string{"Backend"},
"emails": []string{"Communications"},
"sms": []string{"Communications"},
"posts": []string{"Headless CMS"},
"tags": []string{"Headless CMS"},
"feeds": []string{"Headless CMS"},
"chat": []string{"Communications"},
"geocoding": []string{"Logistics"},
"places": []string{"Logistics"},
"routing": []string{"Logistics"},
"etas": []string{"Logistics"},
"notes": []string{"Misc"},
"messages": []string{"Misc"},
}
func saveSpec(originalMarkDown []byte, contentDir, serviceName string, spec *openapi3.Swagger) error {
for _, v := range specTypes {
fmt.Println("Processing ", v.name)
contentFile := filepath.Join(contentDir, serviceName+v.filePostFix)
var app []byte
if v.includeReadme {
app = originalMarkDown
}
tags := []string{v.tag}
serviceTags, ok := servicesToTags[serviceName]
if ok {
tags = append(tags, serviceTags...)
}
tagsString := "\n- " + strings.Join(tags, "\n- ")
err := ioutil.WriteFile(contentFile, append([]byte("---\ntitle: "+serviceName+v.titlePostFix+"\nservicename: "+serviceName+"\nlabels: "+tagsString+"\n---\n"), app...), 0777)
if err != nil {
fmt.Printf("Failed to write post content to %v:\n%v\n", err)
os.Exit(1)
}
fi, err := os.OpenFile(contentFile, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
return err
}
tmpl, err := template.New("test").Funcs(template.FuncMap{
"params": func(p openapi3.Parameters) string {
ls := ""
for _, v := range p {
//if v.Value.In == "body" {
bs, _ := v.MarshalJSON()
ls += string(bs) + ", "
//}
} }
} return ls
},
return "Schema related to " + ref + " not found" // @todo should take SpecRef here not RequestBodyRef
"schemaJSON": func(prepend int, ref string) string {
}, for k, v := range spec.Components.Schemas {
"schemaDescription": func(ref string) string { // ie. #/components/requestBodies/PostsSaveRequest contains
for k, v := range spec.Components.Schemas { // SaveRequest, can't see any other way to correlate
// ie. #/components/requestBodies/PostsSaveRequest contains if strings.HasSuffix(ref, k) {
// SaveRequest, can't see any other way to correlate bs, _ := json.MarshalIndent(schemaToMap(v, spec.Components.Schemas), "", strings.Repeat(" ", prepend)+" ")
if strings.HasSuffix(ref, k) { // last line wont get prepended so we fix that here
return v.Value.Description parts := strings.Split(string(bs), "\n")
// skip if it's only 1 line, ie it's '{}'
if len(parts) <= 1 {
return string(bs)
}
parts[len(parts)-1] = strings.Repeat(" ", prepend) + parts[len(parts)-1]
return strings.Join(parts, "\n")
}
} }
}
return "Schema related to " + ref + " not found" return "Schema related to " + ref + " not found"
}, },
// turn chat/Chat/History "schemaDescription": func(ref string) string {
// to Chat History for k, v := range spec.Components.Schemas {
"titleize": func(s string) string { // ie. #/components/requestBodies/PostsSaveRequest contains
parts := strings.Split(s, "/") // SaveRequest, can't see any other way to correlate
if len(parts) > 2 { if strings.HasSuffix(ref, k) {
return strings.Join(parts[2:], " ") return v.Value.Description
} }
return strings.Join(parts, " ") }
},
"firstResponseRef": func(rs openapi3.Responses) string { return "Schema related to " + ref + " not found"
return rs.Get(200).Ref },
}, // turn chat/Chat/History
}).Parse(templ) // to Chat History
if err != nil { "titleize": func(s string) string {
panic(err) parts := strings.Split(s, "/")
if len(parts) > 2 {
return strings.Join(parts[2:], " ")
}
return strings.Join(parts, " ")
},
"firstResponseRef": func(rs openapi3.Responses) string {
return rs.Get(200).Ref
},
}).Parse(v.template)
if err != nil {
panic(err)
}
err = tmpl.Execute(fi, spec)
if err != nil {
return err
}
} }
return tmpl.Execute(fi, spec) return nil
} }
func schemaToMap(spec *openapi3.SchemaRef, schemas map[string]*openapi3.SchemaRef) map[string]interface{} { func schemaToMap(spec *openapi3.SchemaRef, schemas map[string]*openapi3.SchemaRef) map[string]interface{} {
@@ -226,7 +290,7 @@ func schemaToMap(spec *openapi3.SchemaRef, schemas map[string]*openapi3.SchemaRe
return recurse(spec.Value.Properties) return recurse(spec.Value.Properties)
} }
const templ = ` const defTempl = `
## cURL ## cURL
{{ range $key, $value := .Paths }} {{ range $key, $value := .Paths }}
@@ -238,9 +302,39 @@ being lifted correctly from the proto by the openapi spec generator -->
> curl 'https://api.m3o.com{{ $key }}' \ > curl 'https://api.m3o.com{{ $key }}' \
-H 'micro-namespace: $yourNamespace' \ -H 'micro-namespace: $yourNamespace' \
-H 'authorization: Bearer $yourToken' \ -H 'authorization: Bearer $yourToken' \
-d {{ $value.Post.RequestBody.Ref | schemaJSON }}; -d {{ $value.Post.RequestBody.Ref | schemaJSON 0 }};
# Response # Response
{{ $value.Post.Responses | firstResponseRef | schemaJSON }} {{ $value.Post.Responses | firstResponseRef | schemaJSON 0 }}
` + "```" + `
{{ end }}
`
const microJSTempl = `
## Micro.js
{{ range $key, $value := .Paths }}
### {{ $key | titleize }}
<!-- We use the request body description here as endpoint descriptions are not
being lifted correctly from the proto by the openapi spec generator -->
{{ $value.Post.RequestBody.Ref | schemaDescription }}
` + "```" + `html
<script src="https://web.m3o.com/assets/micro.js"></script>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function (event) {
// Login is only required for endpoints doing authorization
Micro.requireLogin(function () {
Micro.post(
"{{ $key }}",
"micro",
{{ $value.Post.RequestBody.Ref | schemaJSON 8 }},
function (data) {
console.log("Success.");
}
);
});
});
</script>
` + "```" + ` ` + "```" + `
{{ end }} {{ end }}

View File

@@ -27,11 +27,11 @@
{{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }} {{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }}
{{ $projects := where .Site.RegularPages "Section" "projects" }} {{ $projects := where .Site.RegularPages "Section" "projects" }}
{{ $pages = first (default 100 .Site.Params.homePosts) (sort (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) "Date" "desc") }}
<div class="container"> <div class="container">
<section> <section>
<div class="posts"> <div class="posts">
{{ $pages = .Site.Taxonomies.labels.readme }}
{{ range $i,$e := $pages }} {{ range $i,$e := $pages }}
{{if modBool $i 2}} {{if modBool $i 2}}
@@ -58,6 +58,8 @@
{{ end }} {{ end }}
{{ end }} {{ end }}
<!-- todo: do not copypaste it all -->
</div> </div>
</section> </section>
{{ if gt (len $projects) 0}} {{ if gt (len $projects) 0}}

View File

@@ -5,18 +5,23 @@
<header class="article-header"> <header class="article-header">
<div class="thumb"> <div class="thumb">
<div> <div>
<h1>{{ .Title }}</h1> <h1><a href="/{{ .Params.servicename }}">{{ .Params.servicename }}</a></h1>
<div> <div>
<a href="/{{ .Title }}/api"><u>API Spec</u></a> <a href="/{{ .Params.servicename }}"><u>Readme</u></a>
&nbsp; &nbsp;
<a href="{{ $.Site.Params.source }}/tree/master/{{ .Title }}"><u>Source</u></a> <a href="/{{ .Params.servicename }}-microjs"><u>Micro.js</u></a>
&nbsp;
<a href="/{{ .Params.servicename }}/api"><u>API Spec</u></a>
&nbsp;
<a href="{{ $.Site.Params.source }}/tree/master/{{ .Params.servicename }}"><u>Source</u></a>
</div> </div>
<div class="post-meta"> <div class="post-meta">
<!-- <div> <!-- <div>
By {{ .Params.author }} on <time>{{ .Date.Format "January 02, 2006" }}</time> By {{ .Params.author }} on <time>{{ .Date.Format "January 02, 2006" }}</time>
</div> --> </div>
-->
<div class="tags"> <div class="tags">
{{ range (.GetTerms "tags") }} {{ range (.GetTerms "labels") }}
<a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a> <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
{{ end }} {{ end }}
</div> </div>

View File

@@ -30,3 +30,6 @@ markup:
permalinks: permalinks:
post: /:filename post: /:filename
taxonomies:
tag: "labels"

View File

@@ -7,8 +7,13 @@ init:
go get github.com/micro/micro/v3/cmd/protoc-gen-micro go get github.com/micro/micro/v3/cmd/protoc-gen-micro
.PHONY: proto .PHONY: proto
proto: proto:
protoc --proto_path=. --micro_out=. --go_out=:. proto/groups.proto protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/groups.proto
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=. --micro_out=. --go_out=:. proto/groups.proto
@redoc-cli bundle api-groups.json
.PHONY: build .PHONY: build
build: build:
go build -o groups *.go go build -o groups *.go

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.23.0 // protoc-gen-go v1.25.0
// protoc v3.13.0 // protoc v3.6.1
// source: proto/groups.proto // source: proto/groups.proto
package groups package groups