Skip to content

Commit

Permalink
Merge pull request #53 from webdestroya/feat/schema-post
Browse files Browse the repository at this point in the history
feat(reflect): Add method to modify the schema after processing
  • Loading branch information
samlown committed Nov 8, 2022
2 parents a7e9715 + ea9462d commit 9f28aff
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
23 changes: 23 additions & 0 deletions fixtures/custom_type_extend.json
@@ -0,0 +1,23 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/invopop/jsonschema/schema-extend-test",
"$ref": "#/$defs/SchemaExtendTest",
"$defs": {
"SchemaExtendTest": {
"properties": {
"LastName": {
"type": "string",
"description": "some extra words"
},
"middle_name": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"LastName"
]
}
}
}
22 changes: 22 additions & 0 deletions reflect.go
Expand Up @@ -108,7 +108,14 @@ type customSchemaImpl interface {
JSONSchema() *Schema
}

// Function to be run after the schema has been generated.
// this will let you modify a schema afterwards
type extendSchemaImpl interface {
JSONSchemaExtend(*Schema)
}

var customType = reflect.TypeOf((*customSchemaImpl)(nil)).Elem()
var extendType = reflect.TypeOf((*extendSchemaImpl)(nil)).Elem()

// customSchemaGetFieldDocString
type customSchemaGetFieldDocString interface {
Expand Down Expand Up @@ -395,6 +402,8 @@ func (r *Reflector) reflectTypeToSchema(definitions Definitions, t reflect.Type)
panic("unsupported type " + t.String())
}

r.reflectSchemaExtend(definitions, t, st)

// Always try to reference the definition which may have just been created
if def := r.refDefinition(definitions, t); def != nil {
return def
Expand Down Expand Up @@ -422,6 +431,19 @@ func (r *Reflector) reflectCustomSchema(definitions Definitions, t reflect.Type)
return nil
}

func (r *Reflector) reflectSchemaExtend(definitions Definitions, t reflect.Type, s *Schema) *Schema {
if t.Implements(extendType) {
v := reflect.New(t)
o := v.Interface().(extendSchemaImpl)
o.JSONSchemaExtend(s)
if ref := r.refDefinition(definitions, t); ref != nil {
return ref
}
}

return s
}

func (r *Reflector) reflectSliceOrArray(definitions Definitions, t reflect.Type, st *Schema) {
if t == rawMessageType {
return
Expand Down
20 changes: 20 additions & 0 deletions reflect_test.go
Expand Up @@ -310,6 +310,25 @@ type KeyNamed struct {
RenamedByComputation int `jsonschema_description:"Description was preserved"`
}

type SchemaExtendTestBase struct {
FirstName string `json:"FirstName"`
LastName string `json:"LastName"`
Age uint `json:"age"`
MiddleName string `json:"middle_name,omitempty"`
}

type SchemaExtendTest struct {
SchemaExtendTestBase `json:",inline"`
}

func (SchemaExtendTest) JSONSchemaExtend(base *Schema) {
base.Properties.Delete("FirstName")
base.Properties.Delete("age")
val, _ := base.Properties.Get("LastName")
(val).(*Schema).Description = "some extra words"
base.Required = []string{"LastName"}
}

type Expression struct {
Value int `json:"value" jsonschema_extras:"foo=bar=='baz'"`
}
Expand Down Expand Up @@ -444,6 +463,7 @@ func TestSchemaGeneration(t *testing.T) {
}, "fixtures/keynamed.json"},
{MapType{}, &Reflector{}, "fixtures/map_type.json"},
{ArrayType{}, &Reflector{}, "fixtures/array_type.json"},
{SchemaExtendTest{}, &Reflector{}, "fixtures/custom_type_extend.json"},
{Expression{}, &Reflector{}, "fixtures/schema_with_expression.json"},
}

Expand Down

0 comments on commit 9f28aff

Please sign in to comment.