diff --git a/datamodel/high/base/schema.go b/datamodel/high/base/schema.go index dd79d827..4a02ae7d 100644 --- a/datamodel/high/base/schema.go +++ b/datamodel/high/base/schema.go @@ -4,6 +4,7 @@ package base import ( + "encoding/json" "github.com/pb33f/libopenapi/datamodel/high" lowmodel "github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low/base" @@ -492,6 +493,29 @@ func (s *Schema) MarshalYAML() (interface{}, error) { return nb.Render(), nil } +// MarshalJSON will create a ready to render JSON representation of the Schema object. +func (s *Schema) MarshalJSON() ([]byte, error) { + nb := high.NewNodeBuilder(s, s.low) + + // determine index version + idx := s.GoLow().Index + if idx != nil { + if idx.GetConfig().SpecInfo != nil { + nb.Version = idx.GetConfig().SpecInfo.VersionNumeric + } + } + // render node + node := nb.Render() + var renderedJSON map[string]interface{} + + // marshal into struct + _ = node.Decode(&renderedJSON) + + // return JSON bytes + return json.Marshal(renderedJSON) +} + +// MarshalYAMLInline will render out the Schema pointer as YAML, and all refs will be inlined fully func (s *Schema) MarshalYAMLInline() (interface{}, error) { nb := high.NewNodeBuilder(s, s.low) nb.Resolve = true @@ -504,3 +528,25 @@ func (s *Schema) MarshalYAMLInline() (interface{}, error) { } return nb.Render(), nil } + +// MarshalJSONInline will render out the Schema pointer as JSON, and all refs will be inlined fully +func (s *Schema) MarshalJSONInline() ([]byte, error) { + nb := high.NewNodeBuilder(s, s.low) + nb.Resolve = true + // determine index version + idx := s.GoLow().Index + if idx != nil { + if idx.GetConfig().SpecInfo != nil { + nb.Version = idx.GetConfig().SpecInfo.VersionNumeric + } + } + // render node + node := nb.Render() + var renderedJSON map[string]interface{} + + // marshal into struct + _ = node.Decode(&renderedJSON) + + // return JSON bytes + return json.Marshal(renderedJSON) +} diff --git a/datamodel/high/base/schema_test.go b/datamodel/high/base/schema_test.go index 6d7d4109..99a7651c 100644 --- a/datamodel/high/base/schema_test.go +++ b/datamodel/high/base/schema_test.go @@ -844,6 +844,82 @@ allOf: assert.Equal(t, testSpec, string(schemaBytes)) } +func TestNewSchemaProxy_RenderSchema_JSON(t *testing.T) { + testSpec := `type: object +description: something object +` + + var compNode yaml.Node + _ = yaml.Unmarshal([]byte(testSpec), &compNode) + + sp := new(lowbase.SchemaProxy) + + // add a config + idxConfig := index.CreateOpenAPIIndexConfig() + idxConfig.SpecInfo = &datamodel.SpecInfo{ + VersionNumeric: 3, + } + idx := index.NewSpecIndexWithConfig(nil, idxConfig) + + err := sp.Build(context.Background(), nil, compNode.Content[0], idx) + assert.NoError(t, err) + + lowproxy := low.NodeReference[*lowbase.SchemaProxy]{ + Value: sp, + ValueNode: compNode.Content[0], + } + + schemaProxy := NewSchemaProxy(&lowproxy) + compiled := schemaProxy.Schema() + + assert.Equal(t, schemaProxy, compiled.ParentProxy) + + assert.NotNil(t, compiled) + assert.Nil(t, schemaProxy.GetBuildError()) + + // now render it out, it should be identical, but in JSON + schemaBytes, _ := compiled.MarshalJSON() + assert.Equal(t, `{"description":"something object","type":"object"}`, string(schemaBytes)) +} + +func TestNewSchemaProxy_RenderSchema_JSONInline(t *testing.T) { + testSpec := `type: object +description: something object +` + + var compNode yaml.Node + _ = yaml.Unmarshal([]byte(testSpec), &compNode) + + sp := new(lowbase.SchemaProxy) + + // add a config + idxConfig := index.CreateOpenAPIIndexConfig() + idxConfig.SpecInfo = &datamodel.SpecInfo{ + VersionNumeric: 3, + } + idx := index.NewSpecIndexWithConfig(nil, idxConfig) + + err := sp.Build(context.Background(), nil, compNode.Content[0], idx) + assert.NoError(t, err) + + lowproxy := low.NodeReference[*lowbase.SchemaProxy]{ + Value: sp, + ValueNode: compNode.Content[0], + } + + schemaProxy := NewSchemaProxy(&lowproxy) + compiled := schemaProxy.Schema() + + assert.Equal(t, schemaProxy, compiled.ParentProxy) + + assert.NotNil(t, compiled) + assert.Nil(t, schemaProxy.GetBuildError()) + + // now render it out, it should be identical, but in JSON + schemaBytes, _ := compiled.MarshalJSONInline() + assert.Equal(t, `{"description":"something object","type":"object"}`, string(schemaBytes)) +} + func TestNewSchemaProxy_RenderSchemaWithMultipleObjectTypes(t *testing.T) { testSpec := `type: object description: something object