123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- package gen
- import (
- "fmt"
- "os"
- "path/filepath"
- "regexp"
- "strconv"
- "strings"
- . "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common"
- GO "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/translate/got"
- TS "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/translate/tst"
- )
- func CreateProject(mode string) (*Project, error) {
- var (
- err error
- path string
- id string
- files []os.FileInfo
- entity *Entity
- resource *Resource
- directory string
- paramAcceptFiled = map[string]bool{}
- p = &Project{
- Mode: mode,
- SchemasRef: map[string]*Entity{},
- Icons: map[string]string{},
- ReplaceWhenEmpty: map[string]bool{},
- OmitEmpty: map[string]bool{},
- FormatMap: map[string]string{},
- Queries: &QueryDef{},
- Translators: map[string]TranslationFn{
- "go": GO.Translate,
- "angular6": TS.Translate,
- },
- }
- )
- if directory, err = os.Getwd(); err != nil {
- return nil, err
- }
- // Carrega a configuracao default do projeto
- // root := []string{fmt.Sprintf("%s/project.json", directory)}
- // if mode != "" {
- // root = append(root, fmt.Sprintf("%s/project.%s.json", directory, mode))
- // }
- // for _, file := range root {
- // if file == "" {
- // continue
- // }
- // if err = ParseJson(file, p); err != nil {
- // return nil, err
- // }
- // }
- if err = JsonParseMode(fmt.Sprintf("%s/project", directory), mode, p); err != nil {
- return nil, err
- }
- if err = ParseJson("queries.json", &p.Queries); err != nil {
- p.Queries.Blacklistwords = map[string][]string{}
- p.Queries.Queries = map[string]string{}
- }
- if err = loadQueries(p, directory); err != nil {
- return nil, err
- }
- if err = expandQueries(p); err != nil {
- return nil, err
- }
- if err = ParseJson("common.json", &p.Resource); err != nil {
- p.Resource = &Resource{}
- }
- for id, v := range p.Resource.CommonParams {
- if v.ID == "" {
- v.ID = id
- }
- }
- if err = JsonParseMode("env/environment", mode, &p.Environment); err != nil {
- return nil, err
- }
- for id, variable := range p.Environment {
- variable.ID = id
- }
- // Carrega os arquivos de entidades localizados na pasta entities
- path = fmt.Sprintf("%s/entities", directory)
- if files, err = GetFiles(path); err == nil {
- fmt.Println("Read entities...")
- for _, file := range files {
- if file.Name()[0] == '*' {
- continue
- }
- if !file.IsDir() {
- entity = &Entity{}
- if err = ParseJson(filepath.Join(path, file.Name()), entity); err != nil {
- return nil, err
- }
- p.Schemas = append(p.Schemas, entity)
- }
- }
- }
- // Carrega os arquivos de recursos localizados na pasta resources
- path = fmt.Sprintf("%s/resources", directory)
- if files, err = GetFiles(path); err == nil {
- fmt.Println("Read resources...")
- for _, file := range files {
- if file.Name()[0] == '*' {
- continue
- }
- resource = &Resource{}
- if err = ParseJson(filepath.Join(path, file.Name()), resource); err != nil {
- return nil, err
- }
- if file.Name() == "global.json" {
- p.Resource = resource
- } else {
- p.Resources = append(p.Resources, resource)
- }
- }
- }
- // Inicializa variaveis do projeto
- if p.OmitEmpty == nil {
- p.OmitEmpty = map[string]bool{}
- }
- p.ReplaceWhenEmpty = map[string]bool{
- "json": true,
- "bson": true,
- }
- // p.OmitEmpty["json"] = true
- // p.OmitEmpty["bson"] = true
- // Atualiza o mapeamento de entidades e resources
- p.SchemasRef = map[string]*Entity{}
- for _, s := range p.Schemas {
- id = GenericPart.ReplaceAllString(s.ID, "")
- for _, p := range s.Properties {
- if err = p.ParseAutogenerate(); err != nil {
- return nil, err
- }
- }
- p.SchemasRef[id] = s
- p.SchemasRef[id+"Reference"] = SchemaReference(s)
- p.SchemasRef[id+"Input"] = SchemaInput(s)
- }
- for _, r := range p.Resources {
- format := map[string]*Value{}
- for _, f := range r.Formats {
- switch f.Fields {
- case "@all":
- f.Fields = ""
- case "@reference":
- if ref, found := p.SchemasRef[r.Entity+"Reference"]; found {
- fields := []string{}
- for _, propertie := range ref.Properties {
- fields = append(fields, propertie.ID)
- }
- f.Fields = strings.Join(fields, ",")
- }
- }
- format[f.Value] = f
- }
- for _, m := range r.Methods {
- m.Resource = r
- m.Entity = r.Entity
- m.Parameters = map[string]*Parameter{}
- if p.Resource.CommonParams == nil {
- continue
- }
- for _, p1 := range m.ParametersString {
- if p2, ok := p.Resource.CommonParams[p1]; ok {
- m.Parameters[p1] = p2
- } else {
- panic(fmt.Errorf("Param '%s' not defined!", p1))
- }
- }
- for _, param := range m.Parameters {
- if _, ok := paramAcceptFiled[param.ID]; ok {
- continue
- }
- paramAcceptFiled[param.ID] = true
- if param.ConvertTo == "" {
- param.ConvertTo = param.Type
- }
- // if param.Validation != nil {
- // if param.Validation.AcceptRef != nil {
- // for _, accept := range param.Validation.AcceptRef {
- // param.Validation.Accept = append(param.Validation.Accept, format[accept])
- // }
- // }
- // if param.Validation.RejectRef != nil {
- // for _, reject := range param.Validation.RejectRef {
- // param.Validation.Reject = append(param.Validation.Reject, format[reject])
- // }
- // }
- // }
- }
- }
- }
- if err = interpolateProject(p); err != nil {
- return nil, err
- }
- // o, _ := json.Marshal(p)
- readBuildVersion(p, directory)
- return p, nil
- }
- func readBuildVersion(project *Project, directory string) {
- var (
- filename = fmt.Sprintf("%s/buildversion", directory)
- build = ""
- buildInt = 0
- err error
- )
- // defer func() {
- // FilePutContents(filename, strconv.Itoa(buildInt), 0777)
- // }()
- if build, err = FileGetContents(filename); err != nil {
- build = "0"
- }
- buildInt, _ = strconv.Atoi(build)
- buildInt++
- project.BuildVersion = fmt.Sprintf("%s.%d", project.Version, buildInt)
- }
- func SchemaReference(s *Entity) *Entity {
- x := *s
- x.Properties = []*Propertie{}
- for _, p := range s.Properties {
- if p.Reference {
- x.Properties = append(x.Properties, p)
- }
- }
- return &x
- }
- func SchemaInput(s *Entity) *Entity {
- x := *s
- x.Properties = []*Propertie{}
- for _, p := range s.Properties {
- if !p.Readonly {
- x.Properties = append(x.Properties, p)
- }
- }
- return &x
- }
- func interpolateProject(project *Project) (err error) {
- data := map[string]interface{}{
- "baseUrl": project.BaseURL,
- }
- for _, resource := range project.Resources {
- data["entity"] = resource.Entity
- for _, method := range resource.Methods {
- method.Request = ResolveParams(method.Request, data)
- method.Response = ResolveParams(method.Response, data)
- // replace baseurl in scopes
- scopes := []string{}
- for _, scope := range method.Scopes {
- scopes = append(
- scopes,
- ResolveParams(scope, data),
- )
- }
- method.Scopes = scopes
- }
- }
- // enviroment variables
- //
- for _, variable := range project.Environment {
- variable.Default = ResolveParams(variable.Default, data)
- }
- return
- }
- var (
- expandTranscludeExpression = regexp.MustCompile(`"\$\._transclude_":true`)
- expandVarExpression = regexp.MustCompile(`"\$(\.\w+)"`)
- removeAllSpacesExpression = regexp.MustCompile(`(\s|\t|\r|\n)+`)
- )
- func loadQueries(project *Project, directory string) (err error) {
- var (
- files []os.FileInfo
- data string
- queryKey string
- )
- path := fmt.Sprintf("%s/queries", directory)
- if files, err = GetFiles(path); err == nil {
- fmt.Println("Read queries...")
- for _, file := range files {
- if file.Name()[0] == '*' {
- continue
- }
- // resource = &Resource{}
- if data, err = FileGetContents(filepath.Join(path, file.Name())); err != nil {
- return
- }
- queryKey = strings.ReplaceAll(strings.ReplaceAll(file.Name(), "_", ":"), ".json", "")
- data = removeAllSpacesExpression.ReplaceAllString(data, "")
- data = expandTranscludeExpression.ReplaceAllStringFunc(data, func(input string) string {
- return "{._transclude_}"
- })
- data = expandVarExpression.ReplaceAllStringFunc(data, func(input string) string {
- input = strings.TrimLeft(strings.TrimRight(input, `"`), `"$`)
- return fmt.Sprintf("{{%s}}", input)
- })
- project.Queries.Queries[queryKey] = data
- }
- }
- return
- }
- func expandQueries(project *Project) (err error) {
- var (
- newquery string
- found bool
- )
- for key, query := range project.Queries.Queries {
- if len(query) > 0 && query[0] == '$' {
- if newquery, found = project.Queries.Queries[query[1:]]; !found {
- panic(fmt.Errorf("Query `%s` not defined", query[1:]))
- }
- project.Queries.Queries[key] = newquery
- }
- }
- return
- }
|