From 6edc33f330d7e9e43ecc3e226164af864a32f190 Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Wed, 7 May 2025 09:10:08 -0600 Subject: [PATCH] Enable writeOnly --- .gitignore | 2 ++ go.mod | 2 +- go.sum | 4 +-- openapi3/jsonschema.go | 13 ++++------ openapi3/reflect_test.go | 56 ++++++++++++++++++++++++++++++++++++++++ openapi31/jsonschema.go | 6 +---- 6 files changed, 67 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index ed77e49..0dd7783 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ /.vscode /bench-*.txt /vendor +go.work +go.work.sum diff --git a/go.mod b/go.mod index ff3967c..615ab27 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/bool64/dev v0.2.39 github.com/stretchr/testify v1.8.2 github.com/swaggest/assertjson v1.9.0 - github.com/swaggest/jsonschema-go v0.3.73 + github.com/swaggest/jsonschema-go v0.3.74 github.com/swaggest/refl v1.3.1 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 6233c49..18c42e7 100644 --- a/go.sum +++ b/go.sum @@ -33,8 +33,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ= github.com/swaggest/assertjson v1.9.0/go.mod h1:b+ZKX2VRiUjxfUIal0HDN85W0nHPAYUbYH5WkkSsFsU= -github.com/swaggest/jsonschema-go v0.3.73 h1:gU1pBzF3pkZ1GDD3dRMdQoCjrA0sldJ+QcM7aSSPgvc= -github.com/swaggest/jsonschema-go v0.3.73/go.mod h1:qp+Ym2DIXHlHzch3HKz50gPf2wJhKOrAB/VYqLS2oJU= +github.com/swaggest/jsonschema-go v0.3.74 h1:hkAZBK3RxNWU013kPqj0Q/GHGzYCCm9WcUTnfg2yPp0= +github.com/swaggest/jsonschema-go v0.3.74/go.mod h1:qp+Ym2DIXHlHzch3HKz50gPf2wJhKOrAB/VYqLS2oJU= github.com/swaggest/refl v1.3.1 h1:XGplEkYftR7p9cz1lsiwXMM2yzmOymTE9vneVVpaOh4= github.com/swaggest/refl v1.3.1/go.mod h1:4uUVFVfPJ0NSX9FPwMPspeHos9wPFlCMGoPRllUbpvA= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= diff --git a/openapi3/jsonschema.go b/openapi3/jsonschema.go index 7d0149d..1cf4b82 100644 --- a/openapi3/jsonschema.go +++ b/openapi3/jsonschema.go @@ -164,6 +164,8 @@ func (s *SchemaOrRef) toJSONSchema(ctx toJSONSchemaContext) jsonschema.SchemaOrB jso.Format = ss.Format jso.Default = ss.Default jso.ReadOnly = ss.ReadOnly + jso.WriteOnly = ss.WriteOnly + jso.Deprecated = ss.Deprecated if ss.Example != nil { jso.WithExamples(*ss.Example) @@ -186,7 +188,7 @@ func (s *SchemaOrRef) FromJSONSchema(schema jsonschema.SchemaOrBool) { js := schema.TypeObject if js.Ref != nil { - if deprecated, ok := js.ExtraProperties["deprecated"].(bool); ok && deprecated { + if js.Deprecated != nil && *js.Deprecated { s.Schema = (&Schema{}).WithAllOf( SchemaOrRef{ Schema: (&Schema{}).WithDeprecated(true), @@ -230,9 +232,7 @@ func (s *SchemaOrRef) FromJSONSchema(schema jsonschema.SchemaOrBool) { os.Example = &js.Examples[0] } - if deprecated, ok := js.ExtraProperties["deprecated"].(bool); ok { - os.Deprecated = &deprecated - } + os.Deprecated = js.Deprecated if js.Type != nil { if js.Type.SimpleTypes != nil { @@ -309,12 +309,9 @@ func (s *SchemaOrRef) FromJSONSchema(schema jsonschema.SchemaOrBool) { } os.ReadOnly = js.ReadOnly + os.WriteOnly = js.WriteOnly os.UniqueItems = js.UniqueItems - if writeOnly, ok := js.ExtraProperties["writeOnly"].(bool); ok { - os.WriteOnly = &writeOnly - } - for name, val := range js.ExtraProperties { if strings.HasPrefix(name, "x-") { if os.MapOfAnything == nil { diff --git a/openapi3/reflect_test.go b/openapi3/reflect_test.go index 0defcd0..bfc7dd2 100644 --- a/openapi3/reflect_test.go +++ b/openapi3/reflect_test.go @@ -1461,3 +1461,59 @@ func TestSelfReference(t *testing.T) { } }`, reflector.SpecSchema()) } + +func TestReadOnlyWriteOnlyDeprecated(t *testing.T) { + type ExampleObject struct { + Foo string `json:"foo" readOnly:"true"` + Bar string `json:"bar" writeOnly:"true"` + Baz string `json:"baz" deprecated:"true"` + } + + type ExampleResponse struct { + ExampleObject `json:"example"` + } + + type ExampleRequest struct { + ExampleObject `json:"example"` + } + + reflector := openapi3.NewReflector() + op, err := reflector.NewOperationContext("GET", "/some/path") + require.NoError(t, err) + + op.AddReqStructure(ExampleRequest{}) + op.AddRespStructure(ExampleResponse{}) + require.NoError(t, reflector.AddOperation(op)) + + assertjson.EqMarshal(t, `{ + "openapi":"3.0.3","info":{"title":"","version":""}, + "paths":{ + "/some/path":{ + "get":{ + "responses":{ + "200":{ + "description":"OK", + "content":{ + "application/json":{ + "schema":{"$ref":"#/components/schemas/Openapi3TestExampleResponse"} + } + } + } + } + } + } + }, + "components":{ + "schemas":{ + "Openapi3TestExampleObject":{ + "type":"object", + "properties":{"bar":{"type":"string", "writeOnly": true},"baz":{"type":"string", "deprecated": true},"foo":{"type":"string","readOnly":true}} + }, + "Openapi3TestExampleResponse":{ + "type":"object", + "properties":{"example":{"$ref":"#/components/schemas/Openapi3TestExampleObject"}} + } + } + } + }`, reflector.SpecSchema()) +} diff --git a/openapi31/jsonschema.go b/openapi31/jsonschema.go index 77ad222..62429f7 100644 --- a/openapi31/jsonschema.go +++ b/openapi31/jsonschema.go @@ -11,11 +11,7 @@ func isDeprecated(schema jsonschema.SchemaOrBool) *bool { return nil } - if d, ok := schema.TypeObject.ExtraProperties["deprecated"].(bool); ok { - return &d - } - - return nil + return schema.TypeObject.Deprecated } type toJSONSchemaContext struct {