Skip to content

Commit

Permalink
feat: manage map types with additionalProperties (#98)
Browse files Browse the repository at this point in the history
* feat: manage additional properties on JSONSchema

* test: add sample test for map types

* feat: more control when additionalProperties set and Properties set on JSONSchema

* feat: allow AdditionalProperties set to true

* chore: make gofump happy

* test: fix wrong generate query test call

Co-authored-by: srdtrk <[email protected]>

* feat: add check is additionalProperties doesn't contains object definition

---------

Co-authored-by: srdtrk <[email protected]>
  • Loading branch information
bdeneux and srdtrk committed Jun 28, 2024
1 parent 8cb7aa1 commit ed67358
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 3 deletions.
2 changes: 2 additions & 0 deletions integration_test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (s *MySuite) TestMessageComposer() {
s.GenerateMessageTypesTest("testdata/ics721.json")
s.GenerateMessageTypesTest("testdata/dao-dao-core.json")
s.GenerateMessageTypesTest("testdata/axone-objectarium.json")
s.GenerateMessageTypesTest("testdata/map-test.json")
}

func (s *MySuite) TestQueryClient() {
Expand All @@ -106,6 +107,7 @@ func (s *MySuite) TestQueryClient() {
s.GenerateQueryClientTest("testdata/ics721.json")
s.GenerateQueryClientTest("testdata/dao-dao-core.json")
s.GenerateQueryClientTest("testdata/axone-objectarium.json")
s.GenerateQueryClientTest("testdata/map-test.json")
}

func (s *MySuite) TestInterchaintestScaffold() {
Expand Down
139 changes: 139 additions & 0 deletions integration_test/testdata/map-test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
{
"contract_name": "map-test",
"contract_version": "0.0.1",
"idl_version": "1.0.0",
"instantiate": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "InstantiateMsg",
"description": "Instantiate message",
"type": "object",
"additionalProperties": false
},
"execute": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ExecuteMsg",
"description": "Execute messages",
"oneOf": [
{
"title": "Foo",
"type": "object",
"required": [
"foo"
],
"properties": {
"foo": {
"type": "object",
"additionalProperties": false
}
},
"additionalProperties": false
}
]
},
"query": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "QueryMsg",
"description": "Query messages",
"oneOf": [
{
"title": "MapString",
"type": "object",
"required": [
"map_string"
],
"properties": {
"map_string": {
"type": "object",
"required": [
"foo"
],
"properties": {
"foo": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"map_with_value"
],
"properties": {
"map_with_value": {
"type": "object",
"required": [
"foo"
],
"properties": {
"foo": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/Value"
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
"Value": {
"type": "object",
"required": [
"value"
],
"properties": {
"value": {
"type": "string"
}
},
"additionalProperties": false
}
}
},
"migrate": null,
"sudo": null,
"responses": {
"map_string": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "BarResponse",
"type": "object",
"required": [
"foo"
],
"properties": {
"foo": {
"description": "The foo value",
"type": "string"
}
},
"additionalProperties": false
},
"map_with_value": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "BarResponse",
"type": "object",
"required": [
"foo"
],
"properties": {
"foo": {
"description": "The foo value",
"type": "string"
}
},
"additionalProperties": false
}
},
"description": "# map-test",
"title": "map-test"
}
6 changes: 4 additions & 2 deletions pkg/codegen/codegentests/cwics721_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,10 @@ type QueryMsg_OutgoingChannels struct {
}
type ExecuteMsg_ReceiveNft Cw721ReceiveMsg

type ExecuteMsg_Pause struct{}
type ExecuteMsg_Callback CallbackMsg
type (
ExecuteMsg_Pause struct{}
ExecuteMsg_Callback CallbackMsg
)

type ExecuteMsg_AdminCleanAndBurnNft struct {
ClassId string `json:"class_id"`
Expand Down
21 changes: 21 additions & 0 deletions pkg/codegen/properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,27 @@ func getType(name string, schema *schemas.JSONSchema, required *bool, typePrefix
for k := range schema.Properties {
typeStr = strcase.ToCamel(k)
}
case schema.AdditionalProperties.JSONSchema != nil:
if len(schema.Properties) > 0 {
return "", fmt.Errorf("cannot determine the type of object %s: properties and additionalProperties are both defined", name)
}
if schema.AdditionalProperties.JSONSchema.Properties != nil {
return "", fmt.Errorf("cannot determine the type of object %s: a sub-object is defined in 'additionalProperties', which is currently not supported, please report this issue in https://github.com/srdtrk/go-codegen", name)
}

itemType, err := getType(name, schema.AdditionalProperties.JSONSchema, nil, "", false)
if err != nil {
return "", err
}

typeStr = "map[string]" + itemType
isOptional = false
case schema.AdditionalProperties.Bool != nil && *schema.AdditionalProperties.Bool:
if len(schema.Properties) > 0 {
return "", fmt.Errorf("cannot determine the type of object %s: properties and additionalProperties are both defined", name)
}
typeStr = "map[string]any"
isOptional = false
default:
return "", fmt.Errorf("cannot determine the type of object %s", name)
}
Expand Down
16 changes: 15 additions & 1 deletion pkg/schemas/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type JSONSchema struct {
Required []string `json:"required,omitempty"` // Section 5.15.
Properties map[string]*JSONSchema `json:"properties,omitempty"` // Section 5.16.
PatternProperties map[string]*JSONSchema `json:"patternProperties,omitempty"` // Section 5.17.
AdditionalProperties *bool `json:"additionalProperties,omitempty"` // Section 5.18.
AdditionalProperties *JSONSchemaOrBool `json:"additionalProperties,omitempty"` // Section 5.18.
Type TypeList `json:"type,omitempty"` // Section 5.21.
AllOf []*JSONSchema `json:"allOf,omitempty"` // Section 5.22.
AnyOf []*JSONSchema `json:"anyOf,omitempty"` // Section 5.23.
Expand Down Expand Up @@ -83,3 +83,17 @@ func (t *TypeList) UnmarshalJSON(b []byte) error {

return nil
}

// JSONSchemaOrBool represents a JSONSchema or a boolean value.
type JSONSchemaOrBool struct {
JSONSchema *JSONSchema
Bool *bool
}

func (t *JSONSchemaOrBool) UnmarshalJSON(b []byte) error {
if err := json.Unmarshal(b, &t.Bool); err == nil {
return nil
}
t.Bool = nil
return json.Unmarshal(b, &t.JSONSchema)
}

0 comments on commit ed67358

Please sign in to comment.