diff --git a/bundler/bundler.go b/bundler/bundler.go index 55b4438f..49f236a0 100644 --- a/bundler/bundler.go +++ b/bundler/bundler.go @@ -7,11 +7,15 @@ package bundler import ( "errors" "fmt" + "strings" + "github.com/davecgh/go-spew/spew" "github.com/pb33f/libopenapi" "github.com/pb33f/libopenapi/datamodel" - v3 "github.com/pb33f/libopenapi/datamodel/high/v3" + highV3 "github.com/pb33f/libopenapi/datamodel/high/v3" + lowV3 "github.com/pb33f/libopenapi/datamodel/low/v3" "github.com/pb33f/libopenapi/index" + "github.com/pb33f/libopenapi/utils" ) // ErrInvalidModel is returned when the model is not usable. @@ -66,11 +70,11 @@ func BundleBytes(bytes []byte, configuration *datamodel.DocumentConfiguration, o // document will be a valid OpenAPI specification, containing no references. // // Circular references will not be resolved and will be skipped. -func BundleDocument(model *v3.Document) ([]byte, error) { +func BundleDocument(model *highV3.Document) ([]byte, error) { return bundle(model, BundleOptions{RelativeRefHandling: RefHandlingInline}) } -func bundle(model *v3.Document, opts BundleOptions) (_ []byte, err error) { +func bundle(model *highV3.Document, opts BundleOptions) (_ []byte, err error) { rolodex := model.Rolodex idx := rolodex.GetRootIndex() @@ -99,12 +103,57 @@ func bundle(model *v3.Document, opts BundleOptions) (_ []byte, err error) { if err := bundleRefTarget(sequenced, mappedReference, bundledComponents, opts); err != nil { return nil, err } + + model, err = composeDocument(model, bundledComponents) + if err != nil { + return nil, err + } } } return model.Render() } +func composeDocument(model *highV3.Document, comps map[string]*index.ReferenceNode) (*highV3.Document, error) { + // lowModel := model.GoLow() + + // components := lowModel.Components + + for def, component := range comps { + defParts := strings.Split(def, "/") + // TODO: use constant from low model labels + if len(defParts) != 4 || defParts[1] != lowV3.ComponentsLabel { + return nil, fmt.Errorf("unsupported component section: %s", def) + } + spew.Dump(component) + + switch defParts[2] { + case "schemas": + // key := low.KeyReference[string]{ + // Value: defParts[3], + // KeyNode: &yaml.Node{ + // Kind: yaml.ScalarNode, + // Style: yaml.TaggedStyle, + // Tag: "!!str", + // Value: defParts[3], + // }, + // } + // value := low.ValueReference[*base.SchemaProxy]{ + // Reference: low.Reference{}, + // Value: &base.SchemaProxy{}, + // ValueNode: &yaml.Node{}, + // } + _, _ := utils.FindKeyNodeFullTop() + // components.Value.Schemas.Value.Set(key, value) + + default: + return nil, fmt.Errorf("unsupported component type: %s", defParts[2]) + } + } + + return nil, nil +} + func bundleRefTarget(ref, mappedRef *index.ReferenceNode, bundledComponents map[string]*index.ReferenceNode, opts BundleOptions) error { idx := ref.Index if mappedRef == nil { diff --git a/test_specs/minimal_remote_refs/openapi.yaml b/test_specs/minimal_remote_refs/openapi.yaml index 6e2fc34a..b1b52ebb 100644 --- a/test_specs/minimal_remote_refs/openapi.yaml +++ b/test_specs/minimal_remote_refs/openapi.yaml @@ -29,8 +29,27 @@ paths: responses: "200": $ref: ./schemas/components.openapi.yaml#/components/responses/ListAccounts + /api/v1/example: + get: + summary: TODO + description: TODO + tags: + - Account + operationId: placeholder + responses: + "200": + description: > + Foo + content: + application/json: + schema: components: securitySchemes: BearerAuth: type: http scheme: bearer + schemas: + Foobar: + type: string + description: > + Something nice to say.