55 lines
1.4 KiB
Go
55 lines
1.4 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// ChainedVars holds auto-extracted fields from the most-recent response.
|
|
// Keys are formatted as "last_FIELD" (top-level) or "last_PARENT_FIELD"
|
|
// (one level of nesting). Use them in any request as {{last_id}}, etc.
|
|
//
|
|
// The map is replaced entirely on each successful response so stale values
|
|
// from a previous call do not bleed into unrelated requests.
|
|
var ChainedVars = make(map[string]string)
|
|
|
|
// ExtractChained parses body as a JSON object and populates ChainedVars.
|
|
// Non-JSON bodies are silently ignored.
|
|
func ExtractChained(body []byte) {
|
|
var data map[string]interface{}
|
|
if err := json.Unmarshal(body, &data); err != nil {
|
|
return
|
|
}
|
|
next := make(map[string]string)
|
|
flattenJSON(next, "last", data, 0)
|
|
ChainedVars = next
|
|
}
|
|
|
|
// flattenJSON recursively walks obj up to maxDepth levels deep.
|
|
func flattenJSON(dst map[string]string, prefix string, obj map[string]interface{}, depth int) {
|
|
if depth > 1 {
|
|
return
|
|
}
|
|
for k, v := range obj {
|
|
key := prefix + "_" + k
|
|
switch val := v.(type) {
|
|
case string:
|
|
dst[key] = val
|
|
case float64:
|
|
if val == float64(int64(val)) {
|
|
dst[key] = fmt.Sprintf("%d", int64(val))
|
|
} else {
|
|
dst[key] = fmt.Sprintf("%g", val)
|
|
}
|
|
case bool:
|
|
if val {
|
|
dst[key] = "true"
|
|
} else {
|
|
dst[key] = "false"
|
|
}
|
|
case map[string]interface{}:
|
|
flattenJSON(dst, key, val, depth+1)
|
|
}
|
|
}
|
|
}
|