go-quasar-partial-ssr/backend/pkg/ts-rpc/tsTsInfo.go

286 lines
6.7 KiB
Go

// exportable typescript generated from golang
// Copyright (C) 2022 Fabio Prada
package tsrpc
import (
"errors"
"fmt"
"strings"
)
type TSModule struct {
Structs map[string]string
Types map[string]string
Enums map[string]string
Consts map[string]string
GTypes map[string]string
Endpoints map[string]string
}
type TSSouces struct {
Pakages map[string]TSModule
Errors []string
}
func (ts *TSSouces) ensurePackage(p string) {
if _, ok := ts.Pakages[p]; !ok {
ts.Pakages[p] = TSModule{
Structs: make(map[string]string),
Types: make(map[string]string),
Enums: make(map[string]string),
Consts: make(map[string]string),
GTypes: make(map[string]string),
Endpoints: make(map[string]string),
}
return
}
pkg := ts.Pakages[p]
if pkg.Structs == nil {
pkg.Structs = make(map[string]string)
}
if pkg.Types == nil {
pkg.Types = make(map[string]string)
}
if pkg.Enums == nil {
pkg.Enums = make(map[string]string)
}
if pkg.Consts == nil {
pkg.Consts = make(map[string]string)
}
if pkg.GTypes == nil {
pkg.GTypes = make(map[string]string)
}
if pkg.Endpoints == nil {
pkg.Endpoints = make(map[string]string)
}
ts.Pakages[p] = pkg
}
func (ts *TSSouces) findStruct(p string, n string) bool {
if _, ok := ts.Pakages[p]; ok {
if _, ok := ts.Pakages[p].Structs[n]; ok {
return true
}
}
return false
}
func (ts *TSSouces) findType(p string, n string) bool {
if _, ok := ts.Pakages[p]; ok {
if _, ok := ts.Pakages[p].Types[n]; ok {
return true
}
}
return false
}
func (ts *TSSouces) find(p string, n string) bool {
return ts.findType(p, n) || ts.findStruct(p, n)
}
func emptySrtuct(info TSInfo, p string, k string) bool {
s := info.Packages[p].structs[k]
fields := 0
for _, v := range s.Fields {
if !v.Json.Ignore {
fields++
}
}
return fields == 0
}
func structToTs(info TSInfo, p string, k string) (string, []string, error) {
var result = ""
var dependencies = []string{}
fields := 0
s := info.Packages[p].structs[k]
if s.Name == "" {
return "", []string{}, errors.New("name not found")
}
if len(s.Fields) > 0 {
result += fmt.Sprintf("\nexport interface %s {\n", k)
for _, v := range info.Packages[p].structs[k].Fields {
if v.Json.Ignore && !v.Ts.Expand {
continue
}
var typeName = v.TsType
if v.Ts.Type != "" {
typeName = v.Ts.Type
}
if v.Ts.Expand {
sp := strings.Split(v.Name, ".")
pkg := p
name := v.Name
if len(sp) > 1 {
pkg = sp[0]
name = sp[1]
}
for _, v := range info.Packages[pkg].structs[name].Fields {
result += fmt.Sprintf("\t%s: %s;\n", v.Name, v.TsType)
fields++
}
} else {
omitempty := ""
if v.Json.OmitEmpty {
omitempty = "?"
}
if !v.Json.Ignore {
result += fmt.Sprintf("\t%s%s: %s;\n", v.Json.Name, omitempty, typeName)
fields++
}
}
if v.DependOn && v.Ts.Type == "" {
dependencies = append(dependencies, v.TsType)
}
}
result += "}\n"
}
if fields == 0 {
return result, dependencies, fmt.Errorf("struct %s not export fields AT: %s", k, info.Packages[p].structs[k].SourceInfo)
}
return result, dependencies, nil
}
func typeToTs(info TSInfo, p string, k string) (string, []string) {
var result = ""
// var dependencies = []string{}
s := info.Packages[p].types[k]
result = fmt.Sprintf("export type %s = %s\n", s.Name, s.TsType)
return result, []string{}
}
func enumToTs(info TSInfo, p string, k string) string {
var result = ""
s := info.Packages[p].enums[k]
result += fmt.Sprintf("export const Enum%s = {\n", s.Name)
for _, v := range s.Info {
result += fmt.Sprintf("%s: %s,\n", v.Key, v.Value)
}
result += "} as const\n"
return result
}
func constToTs(info TSInfo, p string, k string) string {
var result = ""
s := info.Packages[p].consts[k]
result += fmt.Sprintf("export const %s = %s\n", s.Name, s.Value)
return result
}
func (ts *TSSouces) AddDependencies(info TSInfo, p string, s string, dependencies []string) {
if len(dependencies) > 0 {
for _, v := range dependencies {
pk := p
st := string(v)
if strings.Contains(st, ".") {
sp := strings.Split(st, ".")
if len(sp) == 2 {
pk = sp[0]
st = sp[1]
}
}
if info.findStruct(pk, st) {
if emptySrtuct(info, pk, st) {
ts.Errors = append(ts.Errors, fmt.Sprintf("Empty struct %s.%s AT: %s", pk, st, info.Packages[p].structs[s].SourceInfo))
}
s, d, err := structToTs(info, pk, st)
if err != nil {
ts.Errors = append(ts.Errors, err.Error())
}
ts.ensurePackage(pk)
ts.Pakages[pk].Structs[st] = s
if len(d) > 0 {
ts.AddDependencies(info, pk, st, d)
}
} else if info.findType(pk, st) {
s, _ := typeToTs(info, pk, st)
ts.ensurePackage(pk)
ts.Pakages[pk].Types[st] = s
} else {
ts.Errors = append(ts.Errors, fmt.Sprintf("Dipendence not found %s.%s AT: %s", pk, st, info.Packages[p].structs[s].SourceInfo))
}
}
}
}
func (ts *TSSouces) Populate(info TSInfo) {
ts.Pakages = make(map[string]TSModule)
ts.Errors = []string{}
for p, _ := range info.Packages {
ts.ensurePackage(p)
for _, st := range info.Packages[p].structs {
if st.Typescript {
if len(st.Fields) == 0 {
ts.Errors = append(ts.Errors, fmt.Sprintf("Empty struct %s.%s AT: %s", p, st.Name, info.Packages[p].structs[st.Name].SourceInfo))
}
s, dependencies, err := structToTs(info, p, st.Name)
if err != nil {
ts.Errors = append(ts.Errors, err.Error())
}
ts.Pakages[p].Structs[st.Name] = s
ts.AddDependencies(info, p, st.Name, dependencies)
}
}
for _, t := range info.Packages[p].decs {
ts.Pakages[p].GTypes[t.Name] = fmt.Sprintf("export type %s = %s\n", t.Name, t.Value)
}
for _, e := range info.Packages[p].consts {
ts.Pakages[p].Consts[e.Name] = fmt.Sprint(constToTs(info, p, e.Name))
}
for _, e := range info.Packages[p].enums {
ts.Pakages[p].Enums[e.Name] = fmt.Sprint(enumToTs(info, p, e.Name))
}
for _, t := range info.Packages[p].types {
if t.Typescript {
ts.Pakages[p].Types[t.Name] = fmt.Sprintf("export type %s = %s\n", t.Name, t.TsType)
}
}
if len(info.Packages[p].endpoints) > 0 {
for _, e := range info.Packages[p].endpoints {
/* if e.Request != "" {
a := strings.Split(e.Request, ".")
if len(a) == 2 {
s, d, err := structToTs(info, a[0], a[1])
if err != nil {
ts.Errors = append(ts.Errors, err.Error())
}
fmt.Println(s, d)
}
}
if e.Response != "" {
a := strings.Split(e.Response, ".")
if len(a) == 2 {
s, d, err := structToTs(info, a[0], a[1])
if err != nil {
ts.Errors = append(ts.Errors, err.Error())
}
fmt.Println(s, d)
}
} */
e.VerifyTypes(info, p)
endpoint := e.ToTs(p)
ts.Pakages[p].Endpoints[e.Name] = endpoint
}
}
}
}