forked from ebhomengo/niki
1
0
Fork 0
niki/vendor/github.com/go-openapi/spec/ref.go

321 lines
4.3 KiB
Go
Raw Normal View History

2024-05-14 13:07:09 +00:00
// Copyright 2015 go-swagger maintainers
2024-05-14 13:07:09 +00:00
//
2024-05-14 13:07:09 +00:00
// Licensed under the Apache License, Version 2.0 (the "License");
2024-05-14 13:07:09 +00:00
// you may not use this file except in compliance with the License.
2024-05-14 13:07:09 +00:00
// You may obtain a copy of the License at
2024-05-14 13:07:09 +00:00
//
2024-05-14 13:07:09 +00:00
// http://www.apache.org/licenses/LICENSE-2.0
2024-05-14 13:07:09 +00:00
//
2024-05-14 13:07:09 +00:00
// Unless required by applicable law or agreed to in writing, software
2024-05-14 13:07:09 +00:00
// distributed under the License is distributed on an "AS IS" BASIS,
2024-05-14 13:07:09 +00:00
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2024-05-14 13:07:09 +00:00
// See the License for the specific language governing permissions and
2024-05-14 13:07:09 +00:00
// limitations under the License.
package spec
import (
"bytes"
"encoding/gob"
"encoding/json"
"net/http"
"os"
"path/filepath"
"github.com/go-openapi/jsonreference"
)
// Refable is a struct for things that accept a $ref property
2024-05-14 13:07:09 +00:00
type Refable struct {
Ref Ref
}
// MarshalJSON marshals the ref to json
2024-05-14 13:07:09 +00:00
func (r Refable) MarshalJSON() ([]byte, error) {
2024-05-14 13:07:09 +00:00
return r.Ref.MarshalJSON()
2024-05-14 13:07:09 +00:00
}
// UnmarshalJSON unmarshalss the ref from json
2024-05-14 13:07:09 +00:00
func (r *Refable) UnmarshalJSON(d []byte) error {
2024-05-14 13:07:09 +00:00
return json.Unmarshal(d, &r.Ref)
2024-05-14 13:07:09 +00:00
}
// Ref represents a json reference that is potentially resolved
2024-05-14 13:07:09 +00:00
type Ref struct {
jsonreference.Ref
}
// RemoteURI gets the remote uri part of the ref
2024-05-14 13:07:09 +00:00
func (r *Ref) RemoteURI() string {
2024-05-14 13:07:09 +00:00
if r.String() == "" {
2024-05-14 13:07:09 +00:00
return ""
2024-05-14 13:07:09 +00:00
}
u := *r.GetURL()
2024-05-14 13:07:09 +00:00
u.Fragment = ""
2024-05-14 13:07:09 +00:00
return u.String()
2024-05-14 13:07:09 +00:00
}
// IsValidURI returns true when the url the ref points to can be found
2024-05-14 13:07:09 +00:00
func (r *Ref) IsValidURI(basepaths ...string) bool {
2024-05-14 13:07:09 +00:00
if r.String() == "" {
2024-05-14 13:07:09 +00:00
return true
2024-05-14 13:07:09 +00:00
}
v := r.RemoteURI()
2024-05-14 13:07:09 +00:00
if v == "" {
2024-05-14 13:07:09 +00:00
return true
2024-05-14 13:07:09 +00:00
}
if r.HasFullURL {
2024-05-14 13:07:09 +00:00
//nolint:noctx,gosec
2024-05-14 13:07:09 +00:00
rr, err := http.Get(v)
2024-05-14 13:07:09 +00:00
if err != nil {
2024-05-14 13:07:09 +00:00
return false
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
defer rr.Body.Close()
return rr.StatusCode/100 == 2
2024-05-14 13:07:09 +00:00
}
if !(r.HasFileScheme || r.HasFullFilePath || r.HasURLPathOnly) {
2024-05-14 13:07:09 +00:00
return false
2024-05-14 13:07:09 +00:00
}
// check for local file
2024-05-14 13:07:09 +00:00
pth := v
2024-05-14 13:07:09 +00:00
if r.HasURLPathOnly {
2024-05-14 13:07:09 +00:00
base := "."
2024-05-14 13:07:09 +00:00
if len(basepaths) > 0 {
2024-05-14 13:07:09 +00:00
base = filepath.Dir(filepath.Join(basepaths...))
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
p, e := filepath.Abs(filepath.ToSlash(filepath.Join(base, pth)))
2024-05-14 13:07:09 +00:00
if e != nil {
2024-05-14 13:07:09 +00:00
return false
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
pth = p
2024-05-14 13:07:09 +00:00
}
fi, err := os.Stat(filepath.ToSlash(pth))
2024-05-14 13:07:09 +00:00
if err != nil {
2024-05-14 13:07:09 +00:00
return false
2024-05-14 13:07:09 +00:00
}
return !fi.IsDir()
2024-05-14 13:07:09 +00:00
}
// Inherits creates a new reference from a parent and a child
2024-05-14 13:07:09 +00:00
// If the child cannot inherit from the parent, an error is returned
2024-05-14 13:07:09 +00:00
func (r *Ref) Inherits(child Ref) (*Ref, error) {
2024-05-14 13:07:09 +00:00
ref, err := r.Ref.Inherits(child.Ref)
2024-05-14 13:07:09 +00:00
if err != nil {
2024-05-14 13:07:09 +00:00
return nil, err
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return &Ref{Ref: *ref}, nil
2024-05-14 13:07:09 +00:00
}
// NewRef creates a new instance of a ref object
2024-05-14 13:07:09 +00:00
// returns an error when the reference uri is an invalid uri
2024-05-14 13:07:09 +00:00
func NewRef(refURI string) (Ref, error) {
2024-05-14 13:07:09 +00:00
ref, err := jsonreference.New(refURI)
2024-05-14 13:07:09 +00:00
if err != nil {
2024-05-14 13:07:09 +00:00
return Ref{}, err
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return Ref{Ref: ref}, nil
2024-05-14 13:07:09 +00:00
}
// MustCreateRef creates a ref object but panics when refURI is invalid.
2024-05-14 13:07:09 +00:00
// Use the NewRef method for a version that returns an error.
2024-05-14 13:07:09 +00:00
func MustCreateRef(refURI string) Ref {
2024-05-14 13:07:09 +00:00
return Ref{Ref: jsonreference.MustCreateRef(refURI)}
2024-05-14 13:07:09 +00:00
}
// MarshalJSON marshals this ref into a JSON object
2024-05-14 13:07:09 +00:00
func (r Ref) MarshalJSON() ([]byte, error) {
2024-05-14 13:07:09 +00:00
str := r.String()
2024-05-14 13:07:09 +00:00
if str == "" {
2024-05-14 13:07:09 +00:00
if r.IsRoot() {
2024-05-14 13:07:09 +00:00
return []byte(`{"$ref":""}`), nil
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return []byte("{}"), nil
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
v := map[string]interface{}{"$ref": str}
2024-05-14 13:07:09 +00:00
return json.Marshal(v)
2024-05-14 13:07:09 +00:00
}
// UnmarshalJSON unmarshals this ref from a JSON object
2024-05-14 13:07:09 +00:00
func (r *Ref) UnmarshalJSON(d []byte) error {
2024-05-14 13:07:09 +00:00
var v map[string]interface{}
2024-05-14 13:07:09 +00:00
if err := json.Unmarshal(d, &v); err != nil {
2024-05-14 13:07:09 +00:00
return err
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return r.fromMap(v)
2024-05-14 13:07:09 +00:00
}
// GobEncode provides a safe gob encoder for Ref
2024-05-14 13:07:09 +00:00
func (r Ref) GobEncode() ([]byte, error) {
2024-05-14 13:07:09 +00:00
var b bytes.Buffer
2024-05-14 13:07:09 +00:00
raw, err := r.MarshalJSON()
2024-05-14 13:07:09 +00:00
if err != nil {
2024-05-14 13:07:09 +00:00
return nil, err
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
err = gob.NewEncoder(&b).Encode(raw)
2024-05-14 13:07:09 +00:00
return b.Bytes(), err
2024-05-14 13:07:09 +00:00
}
// GobDecode provides a safe gob decoder for Ref
2024-05-14 13:07:09 +00:00
func (r *Ref) GobDecode(b []byte) error {
2024-05-14 13:07:09 +00:00
var raw []byte
2024-05-14 13:07:09 +00:00
buf := bytes.NewBuffer(b)
2024-05-14 13:07:09 +00:00
err := gob.NewDecoder(buf).Decode(&raw)
2024-05-14 13:07:09 +00:00
if err != nil {
2024-05-14 13:07:09 +00:00
return err
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
return json.Unmarshal(raw, r)
2024-05-14 13:07:09 +00:00
}
func (r *Ref) fromMap(v map[string]interface{}) error {
2024-05-14 13:07:09 +00:00
if v == nil {
2024-05-14 13:07:09 +00:00
return nil
2024-05-14 13:07:09 +00:00
}
if vv, ok := v["$ref"]; ok {
2024-05-14 13:07:09 +00:00
if str, ok := vv.(string); ok {
2024-05-14 13:07:09 +00:00
ref, err := jsonreference.New(str)
2024-05-14 13:07:09 +00:00
if err != nil {
2024-05-14 13:07:09 +00:00
return err
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
*r = Ref{Ref: ref}
2024-05-14 13:07:09 +00:00
}
2024-05-14 13:07:09 +00:00
}
return nil
2024-05-14 13:07:09 +00:00
}