|
|
|
package spec
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/zeromicro/go-zero/core/stringx"
|
|
|
|
"github.com/zeromicro/go-zero/tools/goctl/util"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
bodyTagKey = "json"
|
|
|
|
formTagKey = "form"
|
|
|
|
pathTagKey = "path"
|
|
|
|
headerTagKey = "header"
|
|
|
|
defaultSummaryKey = "summary"
|
|
|
|
)
|
|
|
|
|
|
|
|
var definedKeys = []string{bodyTagKey, formTagKey, pathTagKey, headerTagKey}
|
|
|
|
|
|
|
|
func (s Service) JoinPrefix() Service {
|
|
|
|
var groups []Group
|
|
|
|
for _, g := range s.Groups {
|
|
|
|
prefix := strings.TrimSpace(g.GetAnnotation(RoutePrefixKey))
|
|
|
|
prefix = strings.ReplaceAll(prefix, `"`, "")
|
|
|
|
var routes []Route
|
|
|
|
for _, r := range g.Routes {
|
|
|
|
r.Path = path.Join("/", prefix, r.Path)
|
|
|
|
routes = append(routes, r)
|
|
|
|
}
|
|
|
|
g.Routes = routes
|
|
|
|
groups = append(groups, g)
|
|
|
|
}
|
|
|
|
s.Groups = groups
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
// Routes returns all routes in api service
|
|
|
|
func (s Service) Routes() []Route {
|
|
|
|
var result []Route
|
|
|
|
for _, group := range s.Groups {
|
|
|
|
result = append(result, group.Routes...)
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tags returns all tags in Member
|
|
|
|
func (m Member) Tags() []*Tag {
|
|
|
|
tags, err := Parse(m.Tag)
|
|
|
|
if err != nil {
|
|
|
|
panic(m.Tag + ", " + err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return tags.Tags()
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsOptional returns true if tag is optional
|
|
|
|
func (m Member) IsOptional() bool {
|
|
|
|
if !m.IsBodyMember() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
tag := m.Tags()
|
|
|
|
for _, item := range tag {
|
|
|
|
if item.Key == bodyTagKey {
|
|
|
|
if stringx.Contains(item.Options, "optional") {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsOmitEmpty returns true if tag contains omitempty
|
|
|
|
func (m Member) IsOmitEmpty() bool {
|
|
|
|
if !m.IsBodyMember() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
tag := m.Tags()
|
|
|
|
for _, item := range tag {
|
|
|
|
if item.Key == bodyTagKey {
|
|
|
|
if stringx.Contains(item.Options, "omitempty") {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPropertyName returns json tag value
|
|
|
|
func (m Member) GetPropertyName() (string, error) {
|
|
|
|
tags := m.Tags()
|
|
|
|
for _, tag := range tags {
|
|
|
|
if stringx.Contains(definedKeys, tag.Key) {
|
|
|
|
if tag.Name == "-" {
|
|
|
|
return util.Untitle(m.Name), nil
|
|
|
|
}
|
|
|
|
return tag.Name, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", errors.New("json property name not exist, member: " + m.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetComment returns comment value of Member
|
|
|
|
func (m Member) GetComment() string {
|
|
|
|
return strings.TrimSpace(m.Comment)
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsBodyMember returns true if contains json tag
|
|
|
|
func (m Member) IsBodyMember() bool {
|
|
|
|
if m.IsInline {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
tags := m.Tags()
|
|
|
|
for _, tag := range tags {
|
|
|
|
if tag.Key == bodyTagKey {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsFormMember returns true if contains form tag
|
|
|
|
func (m Member) IsFormMember() bool {
|
|
|
|
if m.IsInline {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
tags := m.Tags()
|
|
|
|
for _, tag := range tags {
|
|
|
|
if tag.Key == formTagKey {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsTagMember returns true if contains given tag
|
|
|
|
func (m Member) IsTagMember(tagKey string) bool {
|
|
|
|
if m.IsInline {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
tags := m.Tags()
|
|
|
|
for _, tag := range tags {
|
|
|
|
if tag.Key == tagKey {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetEnumOptions return a slice contains all enumeration options
|
|
|
|
func (m Member) GetEnumOptions() []string {
|
|
|
|
if !m.IsBodyMember() {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
tags := m.Tags()
|
|
|
|
for _, tag := range tags {
|
|
|
|
if tag.Key == bodyTagKey {
|
|
|
|
options := tag.Options
|
|
|
|
for _, option := range options {
|
|
|
|
if strings.Index(option, "options=") == 0 {
|
|
|
|
option = strings.TrimPrefix(option, "options=")
|
|
|
|
return strings.Split(option, "|")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBodyMembers returns all json fields
|
|
|
|
func (t DefineStruct) GetBodyMembers() []Member {
|
|
|
|
var result []Member
|
|
|
|
for _, member := range t.Members {
|
|
|
|
if member.IsBodyMember() {
|
|
|
|
result = append(result, member)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetFormMembers returns all form fields
|
|
|
|
func (t DefineStruct) GetFormMembers() []Member {
|
|
|
|
var result []Member
|
|
|
|
for _, member := range t.Members {
|
|
|
|
if member.IsFormMember() {
|
|
|
|
result = append(result, member)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNonBodyMembers returns all have no tag fields
|
|
|
|
func (t DefineStruct) GetNonBodyMembers() []Member {
|
|
|
|
var result []Member
|
|
|
|
for _, member := range t.Members {
|
|
|
|
if !member.IsBodyMember() {
|
|
|
|
result = append(result, member)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetTagMembers returns all given key fields
|
|
|
|
func (t DefineStruct) GetTagMembers(tagKey string) []Member {
|
|
|
|
var result []Member
|
|
|
|
for _, member := range t.Members {
|
|
|
|
if member.IsTagMember(tagKey) {
|
|
|
|
result = append(result, member)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// JoinedDoc joins comments and summary value in AtDoc
|
|
|
|
func (r Route) JoinedDoc() string {
|
|
|
|
doc := r.AtDoc.Text
|
|
|
|
if r.AtDoc.Properties != nil {
|
|
|
|
doc += r.AtDoc.Properties[defaultSummaryKey]
|
|
|
|
}
|
|
|
|
doc += strings.Join(r.Docs, " ")
|
|
|
|
return strings.TrimSpace(doc)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAnnotation returns the value by specified key from @server
|
|
|
|
func (r Route) GetAnnotation(key string) string {
|
|
|
|
if r.AtServerAnnotation.Properties == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.AtServerAnnotation.Properties[key]
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAnnotation returns the value by specified key from @server
|
|
|
|
func (g Group) GetAnnotation(key string) string {
|
|
|
|
if g.Annotation.Properties == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return g.Annotation.Properties[key]
|
|
|
|
}
|
|
|
|
|
|
|
|
// ResponseTypeName returns response type name of route
|
|
|
|
func (r Route) ResponseTypeName() string {
|
|
|
|
if r.ResponseType == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.ResponseType.Name()
|
|
|
|
}
|
|
|
|
|
|
|
|
// RequestTypeName returns request type name of route
|
|
|
|
func (r Route) RequestTypeName() string {
|
|
|
|
if r.RequestType == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.RequestType.Name()
|
|
|
|
}
|