Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions codegen/pkg/builder/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ func (b *Builder) generateSchemaComponents(name string, spec *base.Schema) []Wri
types = append(types, additionalTypes...)
types = append(types, object)
case spec.OneOf != nil:
object := createOneOf(spec, name)
object, additionalTypes := b.createOneOf(spec, name)
types = append(types, additionalTypes...)
types = append(types, object)
case spec.AnyOf != nil:
slog.Warn("AnyOf not supported, falling back to 'inteface{}'",
Expand Down Expand Up @@ -295,7 +296,8 @@ func (b *Builder) genSchema(sp *base.SchemaProxy, name string) (string, []Writab
types = append(types, object)
return name, types
case schema.OneOf != nil:
object := createOneOf(schema, name)
object, additionalTypes := b.createOneOf(schema, name)
types = append(types, additionalTypes...)
types = append(types, object)
return name, types
case schema.AnyOf != nil:
Expand Down Expand Up @@ -506,16 +508,31 @@ func (b *Builder) createAllOf(schema *base.Schema, name string) (*ClassDeclarati
}, types
}

// createOneOf creates a type declaration for `oneOf` schema.
func createOneOf(schema *base.Schema, name string) *ClassDeclaration {
// TODO: implement `func (v *{{name}}) AsXXX() (XXX, error) { ... }`
// that allows converting one of from `json.RawMessage` to possible variants.
// createOneOf creates a union declaration for `oneOf` schema and emits any
// additional inline branch types needed by the union.
func (b *Builder) createOneOf(schema *base.Schema, name string) (*OneOfDeclaration, []Writable) {
types := make([]Writable, 0)
options := make([]string, 0, len(schema.OneOf))

return &ClassDeclaration{
Description: schemaDoc(name, schema),
Name: name,
Type: "json.RawMessage",
for i, option := range schema.OneOf {
optionName := oneOfOptionName(name, i, option.Schema())
typeName, additionalTypes := b.genSchema(option, optionName)
types = append(types, additionalTypes...)
options = append(options, typeName)
}

return &OneOfDeclaration{
Name: name,
Options: uniqueFunc(options, func(option string) string { return option }),
}, types
}

func oneOfOptionName(name string, index int, schema *base.Schema) string {
if schema != nil && schema.Title != "" {
return name + strcase.ToCamel(schema.Title)
}

return fmt.Sprintf("%sOption%d", name, index+1)
}

func uniqueFields(fields []Property) []Property {
Expand Down
35 changes: 34 additions & 1 deletion openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -7606,6 +7606,7 @@
"apple pay",
"google pay",
"paypal",
"twint",
"na"
],
"title": "Entry Mode"
Expand Down Expand Up @@ -7828,7 +7829,14 @@
"description": "List of hyperlinks for accessing related resources.",
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
"oneOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"$ref": "#/components/schemas/LinkRefund"
}
]
}
},
"events": {
Expand Down Expand Up @@ -7930,6 +7938,30 @@
"minimum": 0,
"title": "Latitude"
},
"LinkRefund": {
"description": "Hypermedia link including allowed minimum and maximum refund amounts.",
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"type": "object",
"properties": {
"min_amount": {
"description": "Minimum allowed amount for the refund.",
"type": "number",
"format": "float"
},
"max_amount": {
"description": "Maximum allowed amount for the refund.",
"type": "number",
"format": "float"
}
}
}
],
"title": "Link Refund"
},
"Lon": {
"description": "Longitude value from the coordinates of the payment location (as received from the payment terminal reader).",
"type": "number",
Expand Down Expand Up @@ -10382,6 +10414,7 @@
"APPLE_PAY",
"GOOGLE_PAY",
"PAYPAL",
"TWINT",
"NONE",
"CHIP",
"MANUAL_ENTRY",
Expand Down
2 changes: 2 additions & 0 deletions sumup/transactions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
HorizontalAccuracy,
Lat,
Link,
LinkRefund,
Lon,
PaymentType,
Problem,
Expand Down Expand Up @@ -66,6 +67,7 @@
"HorizontalAccuracy",
"Lat",
"Link",
"LinkRefund",
"Lon",
"PaymentType",
"Problem",
Expand Down
38 changes: 37 additions & 1 deletion sumup/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ class CardResponse(pydantic.BaseModel):
"qr code pix",
"satispay",
"sofort",
"twint",
],
str,
]
Expand Down Expand Up @@ -2159,6 +2160,7 @@ class ElvCardAccount(pydantic.BaseModel):
"QR_CODE_PIX",
"SATISPAY",
"SOFORT",
"TWINT",
],
str,
]
Expand Down Expand Up @@ -2393,6 +2395,38 @@ class Link(pydantic.BaseModel):
"""


class LinkRefund(pydantic.BaseModel):
"""
Hypermedia link including allowed minimum and maximum refund amounts.
"""

href: typing.Optional[str] = None
"""
URL for accessing the related resource.
Format: uri
"""

max_amount: typing.Optional[float] = None
"""
Maximum allowed amount for the refund.
"""

min_amount: typing.Optional[float] = None
"""
Minimum allowed amount for the refund.
"""

rel: typing.Optional[str] = None
"""
Specifies the relation to the current resource.
"""

type: typing.Optional[str] = None
"""
Specifies the media type of the related resource.
"""


class Person(pydantic.BaseModel):
"""
Person is a schema definition.
Expand Down Expand Up @@ -4269,6 +4303,8 @@ class TransactionFullVatRate(pydantic.BaseModel):
str,
]

TransactionFullLink = typing.Union[Link, LinkRefund]


class TransactionFullLocation(pydantic.BaseModel):
"""
Expand Down Expand Up @@ -4385,7 +4421,7 @@ class TransactionFull(pydantic.BaseModel):
Max: 90
"""

links: typing.Optional[list[Link]] = None
links: typing.Optional[list[TransactionFullLink]] = None
"""
List of hyperlinks for accessing related resources.
"""
Expand Down
Loading