mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-22 15:25:19 +00:00
Docs: Generate client pages (#45)
This commit is contained in:
@@ -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 }}
|
||||||
|
|||||||
@@ -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}}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
<a href="{{ $.Site.Params.source }}/tree/master/{{ .Title }}"><u>Source</u></a>
|
<a href="/{{ .Params.servicename }}-microjs"><u>Micro.js</u></a>
|
||||||
|
|
||||||
|
<a href="/{{ .Params.servicename }}/api"><u>API Spec</u></a>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|||||||
@@ -30,3 +30,6 @@ markup:
|
|||||||
|
|
||||||
permalinks:
|
permalinks:
|
||||||
post: /:filename
|
post: /:filename
|
||||||
|
|
||||||
|
taxonomies:
|
||||||
|
tag: "labels"
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user