Fields ⇄ Map¶
Two mirrored strategies: fieldsToMap (several hub sibling fields aggregate into one spoke map) and mapToFields (a hub map splits into several spoke sibling fields).
What it does¶
Consolidates a fixed, known set of sibling fields into a single free-form map (or the reverse) — the classic "these three separate fields should really just be one config map" API-evolution pattern.
When to use it¶
You're aggregating a small, fixed number of named fields into a map on one side, or splitting a map's known keys back out into individual fields on the other.
Depends on onUnknownSpokeKey/onUnknownHubKey
The direction that splits the map into fields is lossless only if every key actually present in the map is one you've declared — an unknown key with on...Key: Error (the default) makes that direction fail closed at validation time (a genuine schema mismatch, not silently dropped); on...Key: Drop makes it lossy instead (any config using it needs acknowledgeLossy: true). The direction that aggregates fields into the map is always lossless — nothing is dropped, since every source field is explicitly named in hubPaths/spokePaths.
Example: fieldsToMap¶
The hub's separate cpuLimit/memoryLimit fields aggregate into a single limits map on the v2 spoke:
Rule¶
- strategy: FieldsToMap
fieldsToMap:
hubPaths:
- spec.cpuLimit
- spec.memoryLimit
spokeMapPath: spec.limits
keyNames:
spec.cpuLimit: cpu
spec.memoryLimit: memory
Objects¶
Example: mapToFields¶
The structural mirror — the hub's tags map splits into separate envTag/teamTag fields on the v1 spoke:
Rule¶
- strategy: MapToFields
mapToFields:
hubMapPath: spec.tags
spokePaths:
- spec.envTag
- spec.teamTag
keyNames:
spec.envTag: env
spec.teamTag: team
Objects¶
Here, converting hub → spoke splits the map (lossless only if tags never contains a key besides env/team); converting spoke → hub aggregates the two fields back into the map (always lossless).