package smartconfig import ( "fmt" "os" "strings" "github.com/tidwall/gjson" ) // JSONResolver reads values from JSON files. // Usage: ${JSON:/path/to/file.json:json.path} type JSONResolver struct{} // Resolve reads a JSON file and extracts the value at the specified path. func (r *JSONResolver) Resolve(value string) (string, error) { parts := strings.SplitN(value, ":", 2) if len(parts) != 2 { return "", fmt.Errorf("invalid JSON resolver format, expected FILE:PATH") } filePath := parts[0] jsonPath := parts[1] data, err := os.ReadFile(filePath) if err != nil { return "", fmt.Errorf("failed to read JSON file %s: %w", filePath, err) } // gjson supports JSON5 syntax including comments, trailing commas, etc. // Special case: if path is ".", return the entire JSON as a string if jsonPath == "." { return string(data), nil } result := gjson.GetBytes(data, jsonPath) if !result.Exists() { return "", fmt.Errorf("path %s not found in JSON file", jsonPath) } // Return the raw value as a string return result.String(), nil }