@@ -431,6 +431,59 @@ func parseSchemaForDefaults(schema gjson.Result, defaultFields map[string]interf
431431 return true
432432 })
433433
434+ // Handle shorthand_fields by finding defaults from their "replaced_with" or "translate_backwards" paths
435+ shorthandFields := schema .Get ("shorthand_fields" )
436+ if shorthandFields .Exists () && shorthandFields .IsArray () {
437+ shorthandFields .ForEach (func (_ , value gjson.Result ) bool {
438+ ms := value .Map ()
439+ for fieldName := range ms {
440+ fieldSchema := value .Get (fieldName )
441+ replacements := fieldSchema .Get ("deprecation.replaced_with.#.path" ).Array ()
442+ var replacedPaths []string
443+ var pathArray []gjson.Result
444+
445+ if len (replacements ) > 0 {
446+ // replacements is an array of objects with path arrays inside each object.
447+ // Eg; {
448+ // "redis_host":
449+ // "replaced_with": [
450+ // {
451+ // "path": ["redis", "host"]
452+ // }
453+ // ]
454+ // }
455+ // typically there's only one; if multiple, we consider only the first one
456+ pathArray = replacements [0 ].Array ()
457+ } else {
458+ // backward translation gives an array with the path segments
459+ // Eg; {
460+ // "redis_host": {
461+ // "translate_backwards": ["redis", "host"]
462+ // }
463+ // }
464+ backwardTranslation := fieldSchema .Get ("translate_backwards" )
465+ if backwardTranslation .Exists () {
466+ pathArray = backwardTranslation .Array ()
467+ }
468+ }
469+
470+ replacedPaths = make ([]string , len (pathArray ))
471+ for i , segment := range pathArray {
472+ replacedPaths [i ] = segment .String ()
473+ }
474+
475+ if len (replacedPaths ) > 0 {
476+ defaultValue := findDefaultInReplacementPath (schema , replacedPaths )
477+ if defaultValue .Exists () {
478+ defaultFields [fieldName ] = defaultValue .Value ()
479+ }
480+ }
481+
482+ }
483+ return true
484+ })
485+ }
486+
434487 // All credentials' schemas in konnect are embedded under "value" field
435488 // which doesn't match gateway schema or internal go-kong representation
436489 // Thus, merging values from "value" field to the defaultFields map directly
@@ -444,6 +497,64 @@ func parseSchemaForDefaults(schema gjson.Result, defaultFields map[string]interf
444497 return defaultFields
445498}
446499
500+ // findDefaultInReplacementPath traverses the schema to find the default value at the specified path
501+ func findDefaultInReplacementPath (schema gjson.Result , pathSegments []string ) gjson.Result {
502+ schemaFields := schema .Get ("fields" )
503+ if schemaFields .Type == gjson .Null {
504+ schemaFields = schema .Get ("properties" )
505+ }
506+
507+ // Begin iteration from the root schema fields
508+ // current represents the current level in the schema traversal
509+ // when the path is fully traversed, current will hold the default value
510+ // On each iteration, we update current to the next level in the schema, whenever
511+ // the path segment is found.
512+ current := schemaFields
513+
514+ for i , segment := range pathSegments {
515+ var next gjson.Result
516+ isLastSegment := i == len (pathSegments )- 1
517+ isArray := current .IsArray ()
518+
519+ current .ForEach (func (key , value gjson.Result ) bool {
520+ var fieldExists bool
521+ var fieldValue gjson.Result
522+
523+ if isArray {
524+ // For arrays, check if the segment exists in the value
525+ fieldExists = value .Get (segment ).Exists ()
526+ fieldValue = value
527+ } else {
528+ // For objects, check if the key matches the segment
529+ fieldExists = key .String () == segment
530+ fieldValue = current
531+ }
532+
533+ if fieldExists {
534+ if isLastSegment {
535+ next = fieldValue .Get (segment + ".default" )
536+ } else {
537+ next = fieldValue .Get (segment + ".fields" )
538+ if next .Type == gjson .Null {
539+ next = fieldValue .Get (segment + ".properties" )
540+ }
541+ }
542+ // stop iteration by returning false as we have found the field
543+ return false
544+ }
545+ return true
546+ })
547+
548+ if ! next .Exists () {
549+ return gjson.Result {} // Return empty result if path not found
550+ }
551+
552+ current = next
553+ }
554+
555+ return current
556+ }
557+
447558func stripDefaultValuesFromEntity (entity reflect.Value , defaultFields map [string ]interface {}) error {
448559 if entity .Kind () != reflect .Struct {
449560 return fmt .Errorf ("entity is not a struct" )
0 commit comments