This commit is contained in:
2026-08-16 23:42:00 +02:00
parent 6e77154228
commit 92f046b542
32 changed files with 1443 additions and 105 deletions
+45 -1
View File
@@ -19,7 +19,8 @@ func isDescriptionFieldKey(key string) bool {
// PlainDescriptionFromAny coerces legacy description shapes to a single plain
// string: string, {#text}, or arrays of those (joined with newlines). HTML is
// stripped via v1PlainDescription so poll/store never keep ["…"] or markup blobs.
// stripped via v1PlainDescription — use for meta/SEO and feed normalize only.
// V1 process poll / formula bodies use DescriptionFromAny (keeps markup).
func PlainDescriptionFromAny(v any) string {
if v == nil {
return ""
@@ -59,6 +60,49 @@ func PlainDescriptionFromAny(v any) string {
}
}
// DescriptionFromAny coerces legacy description shapes to a single string while
// preserving formula HTML (h1/h2/p/ul/…). Unwraps JSON arrays / #text wrappers
// but does not strip tags — used by V1 process item projection and catalog
// normalize when enhance/formula HTML must reach clients and stay in DB.
func DescriptionFromAny(v any) string {
if v == nil {
return ""
}
switch t := v.(type) {
case string:
return v1PreserveDescription(t)
case []string:
parts := make([]string, 0, len(t))
for _, s := range t {
if p := v1PreserveDescription(s); p != "" {
parts = append(parts, p)
}
}
return strings.Join(parts, "\n")
case []any:
parts := make([]string, 0, len(t))
for _, item := range t {
if p := DescriptionFromAny(item); p != "" {
parts = append(parts, p)
}
}
return strings.Join(parts, "\n")
case map[string]any:
for _, k := range []string{"#text", "text", "value", "description", "body"} {
if p := DescriptionFromAny(t[k]); p != "" {
return p
}
}
return ""
default:
s := strings.TrimSpace(fmt.Sprint(t))
if s == "" || s == "<nil>" {
return ""
}
return v1PreserveDescription(s)
}
}
// coerceScalarText flattens arrays / #text wrappers into a trimmed string without
// HTML stripping (names, brands, stock labels, …).
func coerceScalarText(v any) string {