generated from hashicorp/terraform-provider-scaffolding-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#16: Simplify openapi client responses.
- Loading branch information
Showing
15 changed files
with
1,315 additions
and
818 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,9 +8,6 @@ dist/ | |
*.dll | ||
*.exe | ||
|
||
# Keep windows files with windows line endings | ||
*.winfile eol=crlf | ||
|
||
# Mac | ||
.DS_Store | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// <editor-fold desc="additional-properties" defaultstate="collapsed"> ///////// | ||
|
||
{{range .Types}}{{$addType := .Schema.AdditionalPropertiesType.TypeDecl}} | ||
|
||
// Getter for additional properties for {{.TypeName}}. Returns the specified | ||
// element and whether it was found | ||
func (a {{.TypeName}}) Get(fieldName string) (value {{$addType}}, found bool) { | ||
if a.AdditionalProperties != nil { | ||
value, found = a.AdditionalProperties[fieldName] | ||
} | ||
return | ||
} | ||
|
||
// Setter for additional properties for {{.TypeName}} | ||
func (a *{{.TypeName}}) Set(fieldName string, value {{$addType}}) { | ||
if a.AdditionalProperties == nil { | ||
a.AdditionalProperties = make(map[string]{{$addType}}) | ||
} | ||
a.AdditionalProperties[fieldName] = value | ||
} | ||
|
||
{{if eq 0 (len .Schema.UnionElements) -}} | ||
// Override default JSON handling for {{.TypeName}} to handle AdditionalProperties | ||
func (a *{{.TypeName}}) UnmarshalJSON(b []byte) error { | ||
object := make(map[string]json.RawMessage) | ||
err := json.Unmarshal(b, &object) | ||
if err != nil { | ||
return err | ||
} | ||
{{range .Schema.Properties}} | ||
if raw, found := object["{{.JsonFieldName}}"]; found { | ||
err = json.Unmarshal(raw, &a.{{.GoFieldName}}) | ||
if err != nil { | ||
return fmt.Errorf("error reading '{{.JsonFieldName}}': %w", err) | ||
} | ||
delete(object, "{{.JsonFieldName}}") | ||
} | ||
{{end}} | ||
if len(object) != 0 { | ||
a.AdditionalProperties = make(map[string]{{$addType}}) | ||
for fieldName, fieldBuf := range object { | ||
var fieldVal {{$addType}} | ||
err := json.Unmarshal(fieldBuf, &fieldVal) | ||
if err != nil { | ||
return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) | ||
} | ||
a.AdditionalProperties[fieldName] = fieldVal | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// Override default JSON handling for {{.TypeName}} to handle AdditionalProperties | ||
func (a {{.TypeName}}) MarshalJSON() ([]byte, error) { | ||
var err error | ||
object := make(map[string]json.RawMessage) | ||
{{range .Schema.Properties}} | ||
{{if not .Required}}if a.{{.GoFieldName}} != nil { {{end}} | ||
object["{{.JsonFieldName}}"], err = json.Marshal(a.{{.GoFieldName}}) | ||
if err != nil { | ||
return nil, fmt.Errorf("error marshaling '{{.JsonFieldName}}': %w", err) | ||
} | ||
{{if not .Required}} }{{end}} | ||
{{end}} | ||
for fieldName, field := range a.AdditionalProperties { | ||
object[fieldName], err = json.Marshal(field) | ||
if err != nil { | ||
return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) | ||
} | ||
} | ||
return json.Marshal(object) | ||
} | ||
{{end}} | ||
{{end}} | ||
|
||
// </editor-fold> ////////////////////////////////////////////////////////////// |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
{{- if opts.Generate.StdHTTPServer }}//go:build go1.22 | ||
{{- end }} | ||
// <editor-fold desc="imports" defaultstate="collapsed"> /////////////////////// | ||
|
||
// Package {{.PackageName}} provides primitives to interact with the openapi HTTP API. | ||
// | ||
// Code generated by {{.ModuleName}} version {{.Version}} DO NOT EDIT. | ||
package {{.PackageName}} | ||
|
||
import ( | ||
"bytes" | ||
"compress/gzip" | ||
"context" | ||
"encoding/base64" | ||
"encoding/json" | ||
"encoding/xml" | ||
"errors" | ||
"fmt" | ||
"gopkg.in/yaml.v2" | ||
"io" | ||
"os" | ||
"mime" | ||
"mime/multipart" | ||
"net/http" | ||
"net/url" | ||
"path" | ||
"strings" | ||
"time" | ||
|
||
"github.com/oapi-codegen/runtime" | ||
"github.com/oapi-codegen/nullable" | ||
strictecho "github.com/oapi-codegen/runtime/strictmiddleware/echo" | ||
strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin" | ||
strictiris "github.com/oapi-codegen/runtime/strictmiddleware/iris" | ||
strictnethttp "github.com/oapi-codegen/runtime/strictmiddleware/nethttp" | ||
openapi_types "github.com/oapi-codegen/runtime/types" | ||
"github.com/getkin/kin-openapi/openapi3" | ||
"github.com/go-chi/chi/v5" | ||
"github.com/labstack/echo/v4" | ||
"github.com/gin-gonic/gin" | ||
"github.com/gofiber/fiber/v2" | ||
"github.com/kataras/iris/v12" | ||
"github.com/kataras/iris/v12/core/router" | ||
"github.com/gorilla/mux" | ||
{{- range .ExternalImports}} | ||
{{ . }} | ||
{{- end}} | ||
{{- range .AdditionalImports}} | ||
{{.Alias}} "{{.Package}}" | ||
{{- end}} | ||
) | ||
|
||
// </editor-fold> ////////////////////////////////////////////////////////////// |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// <editor-fold desc="inline" defaultstate="collapsed"> //////////////////////// | ||
|
||
// Base64 encoded, gzipped, json marshaled Swagger object | ||
var swaggerSpec = []string{ | ||
{{range .SpecParts}} | ||
"{{.}}",{{end}} | ||
} | ||
|
||
// GetSwagger returns the content of the embedded swagger specification file | ||
// or error if failed to decode | ||
func decodeSpec() ([]byte, error) { | ||
zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) | ||
if err != nil { | ||
return nil, fmt.Errorf("error base64 decoding spec: %w", err) | ||
} | ||
zr, err := gzip.NewReader(bytes.NewReader(zipped)) | ||
if err != nil { | ||
return nil, fmt.Errorf("error decompressing spec: %w", err) | ||
} | ||
var buf bytes.Buffer | ||
_, err = buf.ReadFrom(zr) | ||
if err != nil { | ||
return nil, fmt.Errorf("error decompressing spec: %w", err) | ||
} | ||
|
||
return buf.Bytes(), nil | ||
} | ||
|
||
var rawSpec = decodeSpecCached() | ||
|
||
// a naive cached of a decoded swagger spec | ||
func decodeSpecCached() func() ([]byte, error) { | ||
data, err := decodeSpec() | ||
return func() ([]byte, error) { | ||
return data, err | ||
} | ||
} | ||
|
||
// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. | ||
func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { | ||
res := make(map[string]func() ([]byte, error)) | ||
if len(pathToFile) > 0 { | ||
res[pathToFile] = rawSpec | ||
} | ||
{{ if .ImportMapping }} | ||
pathPrefix := path.Dir(pathToFile) | ||
{{ end }} | ||
{{ range $key, $value := .ImportMapping }} | ||
for rawPath, rawFunc := range {{ $value.Name }}.PathToRawSpec(path.Join(pathPrefix, "{{ $key }}")) { | ||
if _, ok := res[rawPath]; ok { | ||
// it is not possible to compare functions in golang, so always overwrite the old value | ||
} | ||
res[rawPath] = rawFunc | ||
} | ||
{{- end }} | ||
return res | ||
} | ||
|
||
// GetSwagger returns the Swagger specification corresponding to the generated code | ||
// in this file. The external references of Swagger specification are resolved. | ||
// The logic of resolving external references is tightly connected to "import-mapping" feature. | ||
// Externally referenced files must be embedded in the corresponding golang packages. | ||
// Urls can be supported but this task was out of the scope. | ||
func GetSwagger() (swagger *openapi3.T, err error) { | ||
resolvePath := PathToRawSpec("") | ||
|
||
loader := openapi3.NewLoader() | ||
loader.IsExternalRefsAllowed = true | ||
loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { | ||
pathToFile := url.String() | ||
pathToFile = path.Clean(pathToFile) | ||
getSpec, ok := resolvePath[pathToFile] | ||
if !ok { | ||
err1 := fmt.Errorf("path not found: %s", pathToFile) | ||
return nil, err1 | ||
} | ||
return getSpec() | ||
} | ||
var specData []byte | ||
specData, err = rawSpec() | ||
if err != nil { | ||
return | ||
} | ||
swagger, err = loader.LoadFromData(specData) | ||
if err != nil { | ||
return | ||
} | ||
return | ||
} | ||
|
||
// </editor-fold> ////////////////////////////////////////////////////////////// |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// <editor-fold desc="typedef" defaultstate="collapsed"> /////////////////////// | ||
|
||
{{range .Types}} | ||
{{ if .Schema.Description }}{{ toGoComment .Schema.Description .TypeName }}{{ else }}// {{.TypeName}} defines model for {{.JsonName}}.{{ end }} | ||
type {{.TypeName}} {{if .IsAlias }}={{end}} {{.Schema.TypeDecl}} | ||
{{end}} | ||
|
||
// </editor-fold> ////////////////////////////////////////////////////////////// |
74 changes: 74 additions & 0 deletions
74
internal/idmc/templates/union-and-additional-properties.go.tmpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
{{range .Types}} | ||
|
||
{{$addType := .Schema.AdditionalPropertiesType.TypeDecl}} | ||
{{$typeName := .TypeName -}} | ||
{{$discriminator := .Schema.Discriminator}} | ||
{{$properties := .Schema.Properties -}} | ||
|
||
// Override default JSON handling for {{.TypeName}} to handle AdditionalProperties and union | ||
func (a *{{.TypeName}}) UnmarshalJSON(b []byte) error { | ||
err := a.union.UnmarshalJSON(b) | ||
if err != nil { | ||
return err | ||
} | ||
object := make(map[string]json.RawMessage) | ||
err = json.Unmarshal(b, &object) | ||
if err != nil { | ||
return err | ||
} | ||
{{range .Schema.Properties}} | ||
if raw, found := object["{{.JsonFieldName}}"]; found { | ||
err = json.Unmarshal(raw, &a.{{.GoFieldName}}) | ||
if err != nil { | ||
return fmt.Errorf("error reading '{{.JsonFieldName}}': %w", err) | ||
} | ||
delete(object, "{{.JsonFieldName}}") | ||
} | ||
{{end}} | ||
if len(object) != 0 { | ||
a.AdditionalProperties = make(map[string]{{$addType}}) | ||
for fieldName, fieldBuf := range object { | ||
var fieldVal {{$addType}} | ||
err := json.Unmarshal(fieldBuf, &fieldVal) | ||
if err != nil { | ||
return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) | ||
} | ||
a.AdditionalProperties[fieldName] = fieldVal | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// Override default JSON handling for {{.TypeName}} to handle AdditionalProperties and union | ||
func (a {{.TypeName}}) MarshalJSON() ([]byte, error) { | ||
var err error | ||
b, err := a.union.MarshalJSON() | ||
if err != nil { | ||
return nil, err | ||
} | ||
object := make(map[string]json.RawMessage) | ||
if a.union != nil { | ||
err = json.Unmarshal(b, &object) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
{{range .Schema.Properties}} | ||
{{if not .Required}}if a.{{.GoFieldName}} != nil { {{end}} | ||
object["{{.JsonFieldName}}"], err = json.Marshal(a.{{.GoFieldName}}) | ||
if err != nil { | ||
return nil, fmt.Errorf("error marshaling '{{.JsonFieldName}}': %w", err) | ||
} | ||
{{if not .Required}} }{{end}} | ||
{{end}} | ||
for fieldName, field := range a.AdditionalProperties { | ||
object[fieldName], err = json.Marshal(field) | ||
if err != nil { | ||
return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) | ||
} | ||
} | ||
return json.Marshal(object) | ||
} | ||
{{end}} | ||
|
||
// </editor-fold> ////////////////////////////////////////////////////////////// |
Oops, something went wrong.