Files
mesh-sdk/go/seatdef/refs.go
T
jschoubben 1aca4991d4 mesh-sdk compiles no seat list and imports no contracts module: catalogue takes its seats from the host, whole seats' names leave it (ADR 0635 §1, §4; issue 1966)
catalogue's working set starts empty and a host gives it the seats it read (UseSeats over SeatsFromDefinitions);
the node-engine's verbs and events take the seat's name from the caller. Tests take their seats from seatlisttest.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-05 12:54:23 +01:00

73 lines
1.9 KiB
Go

package seatdef
import "strings"
// ResolveRefs is a schema (its all-string lists as []string, StringLists) with every `{"$ref": "#/defs/<name>"}` replaced by the definition's named type, as the seat
// list's readers need it (a verb's input and answer are one schema each, not a schema and its types). A reference to a
// name the definition does not define stays as it is; nesting deeper than 32 levels stops there.
func ResolveRefs(schema map[string]any, defs map[string]map[string]any) map[string]any {
if schema == nil {
return nil
}
m, _ := StringLists(resolveValue(schema, defs, 0)).(map[string]any)
return m
}
func resolveValue(v any, defs map[string]map[string]any, depth int) any {
if depth > 32 {
return v
}
switch x := v.(type) {
case map[string]any:
if r, ok := x["$ref"].(string); ok {
if d, ok := defs[strings.TrimPrefix(r, "#/defs/")]; ok {
return resolveValue(d, defs, depth+1)
}
}
out := make(map[string]any, len(x))
for k, e := range x {
out[k] = resolveValue(e, defs, depth+1)
}
return out
case []any:
out := make([]any, len(x))
for i, e := range x {
out[i] = resolveValue(e, defs, depth+1)
}
return out
}
return v
}
// StringLists is a schema with every list whose items are all strings (`required`, `enum`) as a []string, the form the
// compiled seat list wrote them in; a JSON decoder reads them as []any.
func StringLists(v any) any {
switch x := v.(type) {
case map[string]any:
out := make(map[string]any, len(x))
for k, e := range x {
out[k] = StringLists(e)
}
return out
case []any:
strs := make([]string, 0, len(x))
for _, e := range x {
s, ok := e.(string)
if !ok {
strs = nil
break
}
strs = append(strs, s)
}
if strs != nil && len(x) > 0 {
return strs
}
out := make([]any, len(x))
for i, e := range x {
out[i] = StringLists(e)
}
return out
}
return v
}