export const LONG_TEXT_KEYS = { containerType: "container_type", tag: "tag", title: "title", content: "content", contentSummary: "content_summary", guideConclusion: "guide_conclusion", keyFacts: "key_facts", sceneImage: "scene_image", checklistOrSteps: "checklist_or_steps", bestTimeOrPeople: "best_time_or_people", avoidPitfalls: "avoid_pitfalls", nextSuggestion: "next_suggestion", poiDefinition: "poi_definition", keyHighlights: "key_highlights", heroImage: "hero_image", backgroundStory: "background_story", bestTime: "best_time", visitSuggestion: "visit_suggestion", routeSummary: "route_summary", routeMeta: "route_meta", routeSteps: "route_steps", onsiteClues: "onsite_clues", realtimeNotice: "realtime_notice", routeWarning: "route_warning", arrivalNextStep: "arrival_next_step", photoConclusion: "photo_conclusion", photoSpots: "photo_spots", compositionTips: "composition_tips", phoneSettings: "phone_settings", lightReminder: "light_reminder", sampleImage: "sample_image", components: "components", checklist: "checklist", suggest: "suggest", commodity: "commodity", actionZone: "action_zone", }; export const LONG_TEXT_FIELD_CONFIG = [ { key: LONG_TEXT_KEYS.containerType }, { key: LONG_TEXT_KEYS.tag }, { key: LONG_TEXT_KEYS.title }, { key: LONG_TEXT_KEYS.content }, { key: LONG_TEXT_KEYS.contentSummary }, { key: LONG_TEXT_KEYS.guideConclusion }, { key: LONG_TEXT_KEYS.keyFacts }, { key: LONG_TEXT_KEYS.sceneImage }, { key: LONG_TEXT_KEYS.checklistOrSteps }, { key: LONG_TEXT_KEYS.bestTimeOrPeople }, { key: LONG_TEXT_KEYS.avoidPitfalls }, { key: LONG_TEXT_KEYS.nextSuggestion }, { key: LONG_TEXT_KEYS.poiDefinition }, { key: LONG_TEXT_KEYS.keyHighlights }, { key: LONG_TEXT_KEYS.heroImage }, { key: LONG_TEXT_KEYS.backgroundStory }, { key: LONG_TEXT_KEYS.bestTime }, { key: LONG_TEXT_KEYS.visitSuggestion }, { key: LONG_TEXT_KEYS.routeSummary }, { key: LONG_TEXT_KEYS.routeMeta }, { key: LONG_TEXT_KEYS.routeSteps }, { key: LONG_TEXT_KEYS.onsiteClues }, { key: LONG_TEXT_KEYS.realtimeNotice }, { key: LONG_TEXT_KEYS.routeWarning }, { key: LONG_TEXT_KEYS.arrivalNextStep }, { key: LONG_TEXT_KEYS.photoConclusion }, { key: LONG_TEXT_KEYS.photoSpots }, { key: LONG_TEXT_KEYS.compositionTips }, { key: LONG_TEXT_KEYS.phoneSettings }, { key: LONG_TEXT_KEYS.lightReminder }, { key: LONG_TEXT_KEYS.sampleImage }, { key: LONG_TEXT_KEYS.components }, { key: LONG_TEXT_KEYS.checklist }, { key: LONG_TEXT_KEYS.suggest }, { key: LONG_TEXT_KEYS.commodity }, { key: LONG_TEXT_KEYS.actionZone }, ]; export const LONG_TEXT_PREVIEW_KEYS = [ LONG_TEXT_KEYS.contentSummary, LONG_TEXT_KEYS.title, LONG_TEXT_KEYS.tag, ]; const CONFIGURED_KEYS = LONG_TEXT_FIELD_CONFIG.map((item) => item.key); export const createLongTextData = () => ({ values: {}, parsedValues: {}, }); const toText = (value) => { if (value === undefined || value === null) return ""; return typeof value === "string" ? value : String(value); }; const shouldParseJSON = (raw) => { if (!raw || typeof raw !== "string") return false; return /^[\s]*[\[{]/.test(raw); }; const tryParseJSON = (raw) => { if (!shouldParseJSON(raw)) { return { ok: false, value: null }; } try { return { ok: true, value: JSON.parse(raw) }; } catch (e) { return { ok: false, value: null }; } }; export const appendLongTextChunk = (target, chunk = {}) => { if (!target || !chunk.contentKey) return target; const key = String(chunk.contentKey); const value = toText(chunk.contentValue); if (!target.values) target.values = {}; if (!target.parsedValues) target.parsedValues = {}; target.values[key] = (target.values[key] || "") + value; const parsed = tryParseJSON(target.values[key]); if (parsed.ok) { target.parsedValues[key] = parsed.value; } else { delete target.parsedValues[key]; } return target; }; export const getLongTextValue = (data, key) => { if (!data || !data.values || !key) return ""; return data.values[key] || ""; }; export const getLongTextParsedValue = (data, key, fallback = undefined) => { if (!data || !data.parsedValues || !key) return fallback; return Object.prototype.hasOwnProperty.call(data.parsedValues, key) ? data.parsedValues[key] : fallback; }; export const getLongTextPreviewText = (data, keys = LONG_TEXT_PREVIEW_KEYS) => { for (const key of keys) { const value = getLongTextValue(data, key); if (value) return value; } return ""; }; export const hasLongTextExtraSections = (data, previewKeys = LONG_TEXT_PREVIEW_KEYS) => { if (!data || !data.values) return false; return Object.keys(data.values).some((key) => !previewKeys.includes(key)); }; export const getLongTextSections = (data) => { if (!data || !data.values) return []; const extraKeys = Object.keys(data.values).filter( (key) => !CONFIGURED_KEYS.includes(key), ); return [...CONFIGURED_KEYS, ...extraKeys] .filter((key) => Object.prototype.hasOwnProperty.call(data.values, key)) .map((key) => ({ contentKey: key, contentValue: getLongTextValue(data, key), parsedValue: getLongTextParsedValue(data, key, null), })); };