Skip to content

Commit 42d106a

Browse files
refactor(schema): denest conditional requirements code using early returns
Flatten deeply nested if statements in NormalizeSchema() callback by using early returns. Also cache path.Last() in a variable to avoid repeated calls. Co-Authored-By: Martin Vasko <Matovidlo2@gmail.com>
1 parent 3c79c91 commit 42d106a

1 file changed

Lines changed: 40 additions & 32 deletions

File tree

internal/pkg/encoding/json/schema/schema.go

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -143,59 +143,67 @@ func NormalizeSchema(schema []byte) ([]byte, error) {
143143
conditionalReqs := make(map[string][]conditionalRequirement)
144144

145145
m.VisitAllRecursive(func(path orderedmap.Path, value any, parent any) {
146+
lastStep := path.Last()
147+
146148
// Required field in a JSON schema should be an array of required nested fields.
147149
// But, for historical reasons, in Keboola components, "required: true" and "required: false" are also used.
148150
// In the UI, this causes the drop-down list to not have an empty value, so the error should be ignored.
149-
if path.Last() == orderedmap.MapStep("required") {
151+
if lastStep == orderedmap.MapStep("required") {
150152
if _, ok := value.(bool); ok {
151153
if parentMap, ok := parent.(*orderedmap.OrderedMap); ok {
152154
parentMap.Delete("required")
153155
}
154156
}
157+
return
155158
}
156159

157160
// Empty enums are removed, we're using those for asynchronously loaded enums.
158-
if path.Last() == orderedmap.MapStep("enum") {
161+
if lastStep == orderedmap.MapStep("enum") {
159162
if arr, ok := value.([]any); ok && len(arr) == 0 {
160163
if parentMap, ok := parent.(*orderedmap.OrderedMap); ok {
161164
parentMap.Delete("enum")
162165
}
163166
}
167+
return
164168
}
165169

166170
// Handle options.dependencies - collect conditional requirements
167171
// Path pattern: .../properties/<fieldName>/options/dependencies
168-
if path.Last() == orderedmap.MapStep("dependencies") {
169-
pathLen := len(path)
170-
if pathLen >= 4 {
171-
// Check if this is options.dependencies pattern
172-
if path[pathLen-2] == orderedmap.MapStep("options") {
173-
// Get the field name (two levels up from "options")
174-
if fieldStep, ok := path[pathLen-3].(orderedmap.MapStep); ok {
175-
// Check if we're inside "properties"
176-
if pathLen >= 4 && path[pathLen-4] == orderedmap.MapStep("properties") {
177-
// Get dependencies map
178-
if depsMap, ok := value.(*orderedmap.OrderedMap); ok {
179-
deps := make(map[string]any)
180-
for _, key := range depsMap.Keys() {
181-
depValue, _ := depsMap.Get(key)
182-
deps[key] = depValue
183-
}
184-
if len(deps) > 0 {
185-
// Calculate parent object path (remove "properties/<fieldName>/options/dependencies")
186-
parentPath := path[:pathLen-4]
187-
parentPathStr := parentPath.String()
188-
conditionalReqs[parentPathStr] = append(conditionalReqs[parentPathStr], conditionalRequirement{
189-
fieldName: fieldStep.Key(),
190-
dependencies: deps,
191-
})
192-
}
193-
}
194-
}
195-
}
196-
}
197-
}
172+
if lastStep != orderedmap.MapStep("dependencies") {
173+
return
174+
}
175+
pathLen := len(path)
176+
if pathLen < 4 {
177+
return
178+
}
179+
if path[pathLen-2] != orderedmap.MapStep("options") {
180+
return
181+
}
182+
fieldStep, ok := path[pathLen-3].(orderedmap.MapStep)
183+
if !ok {
184+
return
185+
}
186+
if path[pathLen-4] != orderedmap.MapStep("properties") {
187+
return
188+
}
189+
depsMap, ok := value.(*orderedmap.OrderedMap)
190+
if !ok {
191+
return
192+
}
193+
deps := make(map[string]any)
194+
for _, key := range depsMap.Keys() {
195+
depValue, _ := depsMap.Get(key)
196+
deps[key] = depValue
197+
}
198+
if len(deps) == 0 {
199+
return
198200
}
201+
parentPath := path[:pathLen-4]
202+
parentPathStr := parentPath.String()
203+
conditionalReqs[parentPathStr] = append(conditionalReqs[parentPathStr], conditionalRequirement{
204+
fieldName: fieldStep.Key(),
205+
dependencies: deps,
206+
})
199207
})
200208

201209
// Process conditional requirements: remove from required arrays and add if/then/else constructs

0 commit comments

Comments
 (0)