fixes
This commit is contained in:
@@ -85,6 +85,13 @@ func normalizeValue(key string, v any) any {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
// Descriptions must be plain scalars (never leftover ["…"] / HTML arrays).
|
||||
if isDescriptionFieldKey(key) {
|
||||
if s := PlainDescriptionFromAny(v); s != "" {
|
||||
return SanitizeText(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
s := strings.TrimSpace(t)
|
||||
@@ -124,6 +131,13 @@ func normalizeValue(key string, v any) any {
|
||||
if text, ok := t["text"]; ok {
|
||||
return normalizeValue(key, text)
|
||||
}
|
||||
// Feed/XML category objects often carry unique_id — flatten to a scalar
|
||||
// so StepResult.Category / processed_products.category get the code.
|
||||
if key == "category" {
|
||||
if id := categoryUniqueIDFromAny(t); id != "" {
|
||||
return id
|
||||
}
|
||||
}
|
||||
nested := make(map[string]any, len(t))
|
||||
for nk, nv := range t {
|
||||
if nn := normalizeValue(canonicalizeKey(nk), nv); nn != nil {
|
||||
@@ -138,6 +152,14 @@ func normalizeValue(key string, v any) any {
|
||||
if len(t) == 0 {
|
||||
return nil
|
||||
}
|
||||
// Scalar-ish fields (name, brand, eprel_id, …): collapse one-element /
|
||||
// joinable arrays so process steps never see []any where a string is expected.
|
||||
if flat := coerceScalarText(t); flat != "" && looksLikeScalarFieldArray(t) {
|
||||
if isDimensionKey(key) && isZeroishString(flat) {
|
||||
return nil
|
||||
}
|
||||
return SanitizeText(flat)
|
||||
}
|
||||
out := make([]any, 0, len(t))
|
||||
for _, item := range t {
|
||||
if nn := normalizeValue(key, item); nn != nil {
|
||||
@@ -160,6 +182,41 @@ func normalizeValue(key string, v any) any {
|
||||
}
|
||||
}
|
||||
|
||||
// looksLikeScalarFieldArray is true when every element coerces to a short scalar
|
||||
// (string/number/#text) — not nested attribute/spec objects.
|
||||
func looksLikeScalarFieldArray(items []any) bool {
|
||||
if len(items) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, item := range items {
|
||||
switch t := item.(type) {
|
||||
case nil:
|
||||
continue
|
||||
case string, float64, float32, int, int64, int32, bool:
|
||||
continue
|
||||
case map[string]any:
|
||||
if _, ok := t["#text"]; ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := t["text"]; ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := t["value"]; ok {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
case []any, []string:
|
||||
return false
|
||||
default:
|
||||
if _, ok := item.(jsonNumberStringer); ok {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isDimensionKey(key string) bool {
|
||||
switch key {
|
||||
case "width", "height", "depth", "weight", "length", "net_width", "net_height", "net_depth", "net_mass":
|
||||
|
||||
Reference in New Issue
Block a user